Jak określić, czy tablica zawiera określoną wartość w Javie?

Mam {[1] } o wartościach takich jak tak:

public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

Biorąc pod uwagę String s, czy istnieje dobry sposób na sprawdzenie, czy VALUES zawiera s?

 1905
Author: Steve Chambers, 2009-07-15

27 answers

Arrays.asList(yourArray).contains(yourValue)

Ostrzeżenie: to nie działa dla tablic prymitywów(patrz komentarze).


Od java-8

Możesz teraz użyć Stream, aby sprawdzić, czy tablica int, double lub long zawiera wartość (odpowiednio za pomocą IntStream, DoubleStream lub LongStream)

Przykład

int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
 2471
Author: camickr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-09 23:39:25

Na początek Wyczyść kod. Mamy (poprawione):

public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

To zmienna statyka, którą FindBugs powie Ci, że jest bardzo niegrzeczna. Powinno być prywatne:

private static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

(zauważ, że możesz upuścić new String[]; bit.)

Więc tablice referencyjne są złe, a w szczególności tutaj chcemy mieć zestaw:

private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
     new String[] {"AB","BC","CD","AE"}
));

(paranoicy, tacy jak ja, mogą czuć się bardziej swobodnie, gdyby to było owinięte Collections.unmodifiableSet - można by to nawet upublicznić.)

"dany ciąg s, czy istnieje dobry sposób sprawdzania, czy wartości zawierają s?"

VALUES.contains(s)

O(1).

 312
Author: Tom Hawtin - tackline,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-09 22:42:04

Możesz użyć ArrayUtils.contains z Apache Commons Lang

public static boolean contains(Object[] array, Object objectToFind)

Zauważ, że ta metoda zwraca false jeśli przekazana tablica to null.

Istnieją również metody dostępne dla prymitywnych tablic wszelkiego rodzaju.

Przykład:

String[] fieldsToInclude = { "id", "name", "location" };

if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
    // Do some stuff.
}
 173
Author: Intracer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-19 20:49:40

Dziwi mnie, że nikt nie zasugerował, aby po prostu zaimplementować go ręcznie: {]}

public static <T> boolean contains(final T[] array, final T v) {
    for (final T e : array)
        if (e == v || v != null && v.equals(e))
            return true;

    return false;
}

Poprawa:

Warunek v != null jest stały wewnątrz metody, zawsze jest ewaluowany do tej samej wartości logicznej podczas wywołania metody. Jeśli więc wejście array jest duże, efektywniej jest ocenić ten warunek tylko raz i możemy użyć uproszczonego / szybszego warunku wewnątrz pętli for na podstawie wyniku. Ulepszona metoda contains():

public static <T> boolean contains2(final T[] array, final T v) {
    if (v == null) {
        for (final T e : array)
            if (e == null)
                return true;
    } else {
        for (final T e : array)
            if (e == v || v.equals(e))
                return true;
    }

    return false;
}
 144
Author: icza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-14 19:56:42

Jeśli tablica nie jest posortowana, będziesz musiał iterować wszystko i wykonać wywołanie równości na każdej z nich.

Jeśli tablica jest posortowana, możesz wykonać wyszukiwanie binarne, jest jedna w klasie Tablice .

Ogólnie rzecz biorąc, jeśli masz zamiar wykonać wiele kontroli członkostwa, możesz chcieć przechowywać wszystko w zestawie, a nie w tablicy.

 65
Author: Uri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-14 15:13:06

Cztery różne sposoby sprawdzania, czy tablica zawiera wartość

1) Użycie Listy:

public static boolean useList(String[] arr, String targetValue) {
    return Arrays.asList(arr).contains(targetValue);
}

2) Używając Zestawu:

public static boolean useSet(String[] arr, String targetValue) {
    Set<String> set = new HashSet<String>(Arrays.asList(arr));
    return set.contains(targetValue);
}

3) za pomocą prostej pętli:

public static boolean useLoop(String[] arr, String targetValue) {
    for (String s: arr) {
        if (s.equals(targetValue))
            return true;
    }
    return false;
}

4) Używanie Tablic.binarySearch ():

Poniższy kod jest błędny, jest tutaj wymieniony dla kompletności. binarySearch() może być używana tylko na posortowanych tablicach. Wynik jest dziwny poniżej. Jest to najlepsza opcja, gdy tablica jest posortowana.

public static boolean binarySearch(String[] arr, String targetValue) {  
            int a = Arrays.binarySearch(arr, targetValue);
            return a > 0;
        }

Szybki Przykład:

String testValue="test";
String newValueNotInList="newValue";
String[] valueArray = { "this", "is", "java" , "test" };
Arrays.asList(valueArray).contains(testValue); // returns true
Arrays.asList(valueArray).contains(newValueNotInList); // returns false
 61
Author: Sireesh Yarlagadda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-04 02:00:36

Jeśli to ma wartość, przeprowadziłem test porównujący 3 sugestie dotyczące prędkości. Wygenerowałem losowe liczby całkowite, przekonwertowałem je na ciąg znaków i dodałem do tablicy. Następnie wyszukałem najwyższą możliwą liczbę / ciąg znaków, co byłoby najgorszym scenariuszem dla aslist ().zawiera().

Przy użyciu tablicy o rozmiarze 10K wyniki Gdzie:

Sort & Search   : 15
Binary Search   : 0
asList.contains : 0

Przy użyciu tablicy 100K wyniki Gdzie:

Sort & Search   : 156
Binary Search   : 0
asList.contains : 32

Więc jeśli tablica jest tworzona w posortowanej kolejności, wyszukiwanie binarne jest najszybsze, inaczej aslist ()./ align = "left" / Jeśli masz wiele wyszukiwań, to może warto posortować tablicę tak, aby można było użyć wyszukiwania binarnego. Wszystko zależy od twojej aplikacji.

Myślę, że takich rezultatów oczekuje większość ludzi. Oto kod testu:
import java.util.*;

public class Test
{
    public static void main(String args[])
    {
        long start = 0;
        int size = 100000;
        String[] strings = new String[size];
        Random random = new Random();


        for (int i = 0; i < size; i++)
            strings[i] = "" + random.nextInt( size );

        start = System.currentTimeMillis();
        Arrays.sort(strings);
        System.out.println(Arrays.binarySearch(strings, "" + (size - 1) ));
        System.out.println("Sort & Search : " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(Arrays.binarySearch(strings, "" + (size - 1) ));
        System.out.println("Search        : " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(Arrays.asList(strings).contains( "" + (size - 1) ));
        System.out.println("Contains      : " + (System.currentTimeMillis() - start));
    }
}
 46
Author: camickr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-15 01:34:20

Zamiast używać składni quick array initialsation Do możesz po prostu zainicjalizować ją jako listę od razu w podobny sposób używając tablic.metoda asList np.:

public static final List<String> STRINGS = Arrays.asList("firstString", "secondString" ...., "lastString");

Wtedy możesz zrobić (jak wyżej): STRINGS.contains("the string you want to find");

 29
Author: Mark Rhodes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-05 07:48:46

W Javie 8 można utworzyć strumień i sprawdzić, czy jakieś wpisy w strumieniu pasują "s":

String[] values = {"AB","BC","CD","AE"};
boolean sInArray = Arrays.stream(values).anyMatch("s"::equals);

Lub jako metoda ogólna:

public static <T> boolean arrayContains(T[] array, T value) {
    return Arrays.stream(array).anyMatch(value::equals);
}
 29
Author: assylias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-13 15:02:36

Możesz użyć klasy tablic do wykonania binarnego wyszukiwania wartości. Jeśli tablica nie jest posortowana, będziesz musiał użyć funkcji sortowania w tej samej klasie, aby posortować tablicę, a następnie przeszukać ją.

 23
Author: Thomas Owens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-23 19:08:04

ObStupidAnswer (ale chyba gdzieś tu jest lekcja):

enum Values {
    AB, BC, CD, AE
}

try {
    Values.valueOf(s);
    return true;
} catch (IllegalArgumentException exc) {
    return false;
}
 15
Author: Tom Hawtin - tackline,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-15 01:18:26

Właściwie, jeśli używasz HashSet tak, jak zaproponował Tom Hawtin, nie musisz się martwić o sortowanie, a twoja prędkość jest taka sama jak w przypadku wyszukiwania binarnego na wstępnie posortowanej tablicy, prawdopodobnie nawet szybciej.

Wszystko zależy od tego, jak Twój kod jest ustawiony, oczywiście, ale z mojego punktu widzenia kolejność byłaby:

Na niesortowanej tablicy:

  1. HashSet
  2. asList
  3. sort & Binary

Na posortowanym tablica:

  1. HashSet
  2. binarny
  3. asList

Tak czy inaczej, HashSet ftw

 11
Author: not,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-02 16:36:25

Jeśli masz bibliotekę zbiorów google, odpowiedź Toma można znacznie uprościć za pomocą ImmutableSet (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html)

To naprawdę usuwa wiele bałaganu z proponowanej inicjalizacji

private static final Set<String> VALUES =  ImmutableSet.of("AB","BC","CD","AE");
 9
Author: jhodges,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-19 14:13:40

Jedno możliwe rozwiązanie:

import java.util.Arrays;
import java.util.List;

public class ArrayContainsElement {
  public static final List<String> VALUES = Arrays.asList("AB", "BC", "CD", "AE");

  public static void main(String args[]) {

      if (VALUES.contains("AB")) {
          System.out.println("Contains");
      } else {
          System.out.println("Not contains");
      }
  }
}
 7
Author: Christian Giménez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-08 03:29:05

Programiści często robią:

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);

Powyższy kod działa, ale nie ma potrzeby konwertowania listy do Ustawienia jako pierwszej. Konwersja listy do zestawu wymaga dodatkowego czasu. Może być tak proste jak:

Arrays.asList(arr).contains(targetValue);

Lub

   for(String s: arr){
        if(s.equals(targetValue))
            return true;
    }

return false;

Pierwszy jest bardziej czytelny niż drugi.

 6
Author: Xar E Ahmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-25 07:24:12

W Java 8 używaj strumieni.

List<String> myList =
Arrays.asList("a1", "a2", "b1", "c2", "c1");

myList
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
 6
Author: Shineed Basheer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-28 06:40:26

Używanie prostej pętli jest najskuteczniejszym sposobem na to.

boolean useLoop(String[] arr, String targetValue) {
    for(String s: arr){
        if(s.equals(targetValue))
            return true;
    }
    return false;
}

Dzięki Uprzejmości Programcreek

 4
Author: Ryan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-07 19:53:57
  1. Dla tablic o ograniczonej długości użyj następujących (podanych przez camickr ). Jest to powolne w przypadku wielokrotnych kontroli, szczególnie w przypadku dłuższych tablic (wyszukiwanie liniowe).

     Arrays.asList(...).contains(...)
    
  2. Dla szybkiej wydajności, jeśli wielokrotnie sprawdzasz przed większym zestawem elementów

    • Tablica jest niewłaściwą strukturą. Użyj a TreeSet i dodać do niego każdy element. Sortuje elementy i posiada szybką metodę exist() (binary Szukaj).

    • Jeśli elementy zaimplementują Comparable & chcesz TreeSet posortować odpowiednio:

      ElementClass.compareTo() metoda musi być zgodna z ElementClass.equals(): Zobacz triady nie pokazujące się do walki? (Java Set brak elementu)

      TreeSet myElements = new TreeSet();
      
      // Do this for each element (implementing *Comparable*)
      myElements.add(nextElement);
      
      // *Alternatively*, if an array is forceably provided from other code:
      myElements.addAll(Arrays.asList(myArray));
      
    • W przeciwnym razie użyj własnego Comparator:

      class MyComparator implements Comparator<ElementClass> {
           int compareTo(ElementClass element1; ElementClass element2) {
                // Your comparison of elements
                // Should be consistent with object equality
           }
      
           boolean equals(Object otherComparator) {
                // Your equality of comparators
           }
      }
      
      
      // construct TreeSet with the comparator
      TreeSet myElements = new TreeSet(new MyComparator());
      
      // Do this for each element (implementing *Comparable*)
      myElements.add(nextElement);
      
    • Wypłata: sprawdź istnienie jakiegoś elementu:

      // Fast binary search through sorted elements (performance ~ log(size)):
      boolean containsElement = myElements.exists(someElement);
      
 3
Author: Glen Best,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:30

Tablice.aslist () - > następnie wywołanie metody contains() zawsze będzie działać, ale algorytm wyszukiwania jest znacznie lepszy, ponieważ nie trzeba tworzyć lekkiego owijania listy wokół tablicy, czyli czym są tablice.aslist ().

public boolean findString(String[] strings, String desired){
   for (String str : strings){
       if (desired.equals(str)) {
           return true;
       }
   }
   return false; //if we get here… there is no desired String, return false.
}
 2
Author: WIll,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-17 23:29:40

Użyj Array.BinarySearch(array,obj) do znalezienia danego obiektu w tablicy lub nie. Ex:

if (Array.BinarySearch(str, i) > -1) -->true --exists

False --not exists

 1
Author: Avenger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-30 07:18:55

Jestem bardzo spóźniony, aby dołączyć do tej dyskusji, ale ponieważ moje podejście do rozwiązania tego problemu, kiedy miałem do czynienia z nim kilka lat temu, było nieco inne niż inne odpowiedzi już zamieszczone tutaj, zamieszczam To rozwiązanie, którego użyłem w tym czasie, tutaj, na wypadek, gdyby ktoś uznał to za przydatne: (metoda contains() jest ArrayUtils.in() w tym kodzie.)

Przedmioty.java

public class ObjectUtils{

/**
 * A null safe method to detect if two objects are equal.
 * @param object1
 * @param object2
 * @return true if either both objects are null, or equal, else returns false.
 */
public static boolean equals(Object object1,Object object2){
    return object1==null?object2==null:object1.equals(object2);
}

}

ArrayUtils.java

public class ArrayUtils{
/**
 * Find the index of of an object is in given array, starting from given inclusive index.
 * @param ts  Array to be searched in.
 * @param t  Object to be searched.
 * @param start  The index from where the search must start. 
 * @return Index of the given object in the array if it is there, else -1. 
 */
public static <T> int indexOf(final T[] ts, final T t, int start){
    for(int i = start; i < ts.length;++i)
        if(ObjectUtils.equals(ts[i],t))
            return i;
    return -1;
}

/**
 * Find the index of of an object is in given array, starting from 0;
 * @param ts  Array to be searched in.
 * @param t  Object to be searched.
 * @return  indexOf(ts,t,0)
 */
public static <T> int indexOf(final T[] ts, final T t){
    return indexOf(ts, t, 0);
}

/**
 * Detect if the given object is in the given array.
 * @param ts  Array to be searched in.
 * @param t  Object to be searched.
 * @return  If indexOf(ts,t) is greater than -1.
 */
public static <T> boolean in(final T[] ts, final T t){
    return indexOf(ts, t) > -1 ;
}

}

Jak widać w powyższym kodzie, istnieją inne metody użytkowe ObjectUtils.equals() i ArrayUtils.indexOf(), które były używane również w innych miejscach.

 1
Author: Abhishek Oza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-23 13:25:35

Może być tak proste jak:

String[] VALUE = new String[] {"AB","BC","CD","AE"};
Arrays.asList(VALUE).contains(s);
 1
Author: Aaron Chen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-27 04:14:20

Sprawdź to

String[] VALUES = new String[] {"AB","BC","CD","AE"};
String s;

for(int i=0; i< VALUES.length ; i++)
{
    if ( VALUES[i].equals(s) )
    { 
        // do your stuff
    } 
    else{    
        //do your stuff
    }
}
 1
Author: SubbaRao Boddu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-08 03:26:35

Spróbuj tego:

ArrayList<Integer> arrlist = new ArrayList<Integer>(8);

// use add() method to add elements in the list
arrlist.add(20);
arrlist.add(25);
arrlist.add(10);
arrlist.add(15);

boolean retval = arrlist.contains(10);
if (retval == true) {
    System.out.println("10 is contained in the list");
}
else {
    System.out.println("10 is not contained in the list");
}
 1
Author: Mr.G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-08 03:27:44

Jeśli nie chcesz, aby rozróżniano wielkość liter

Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);
 1
Author: Akhil babu K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-21 17:16:22

Oto mój prosty kod wykorzystujący klasę Arrays z pakietu util. Można to zrobić na wiele innych sposobów, ale coraz pytanie, to podejście przyszło mi do głowy pierwszy.

String a[] = {"abc","xyz","pqr"};
System.out.println(Arrays.asList(a).contains("abc")); //will return true
System.out.println(Arrays.asList(a).contains("abcd")); // will return false
 0
Author: Debjyoti Pandit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-03 13:17:04

Utwórz wartość logiczną początkowo ustawioną na false. Uruchom pętlę, aby sprawdzić każdą wartość w tablicy i porównać z wartością, którą sprawdzasz. Jeśli kiedykolwiek uzyskasz dopasowanie, ustaw wartość logiczną na true i zatrzymaj pętlę. Następnie potwierdź, że wartość logiczna jest prawdziwa.

 -1
Author: mandy1339,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-17 19:37:40