Wie bestimme ich, ob ein Array in Java einen bestimmten Wert enthält?


2276

Ich habe einen String[]mit Werten wie diesen:

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

Gibt String ses eine gute Möglichkeit zu testen, ob es VALUESenthält s?


5
Weit herum, aber Sie können eine for-Schleife verwenden: "for (String s: VALUES) if (s.equals (" MYVALUE ")) gibt true zurück;
Zack

70
@camickr. Auf Ihre Frage habe ich diese Frage und Ihre Antwort - jetzt - positiv bewertet, weil ich dadurch 30 Minuten und 20 Zeilen Code gespart habe, die hässlich für Schleifen geschrieben wurden. Ich habe es vor drei Jahren nicht gelesen. (Übrigens, danke :))
Verfolgung

3
@ camickr - Ich habe eine fast identische Situation mit dieser: stackoverflow.com/a/223929/12943 Es werden immer wieder Stimmen abgegeben, aber es war nur ein Kopieren / Einfügen aus der Dokumentation von sun. Ich denke, die Punktzahl hängt davon ab, wie viel Hilfe Sie geleistet haben und nicht davon, wie viel Aufwand Sie investiert haben - und vor allem davon, wie schnell Sie sie veröffentlichen! Vielleicht sind wir auf John Skeets Geheimnis gestoßen! Gute Antwort, +1 für dich.
Bill K

1
Wenn Sie Apache Commons verwenden, erledigt org.apache.commons.lang.ArrayUtils.contains () dies für Sie.
Mr. Boy

34
@camickr, weil Leute wie ich eine Frage googeln, auf das SO-Ergebnis klicken, Ihre Antwort sehen, sie testen, es funktioniert, die Antwort positiv bewerten und dann gehen.
Aequitas

Antworten:


2923
Arrays.asList(yourArray).contains(yourValue)

Warnung: Dies funktioniert nicht für Arrays von Grundelementen (siehe Kommentare).


Schon seit Sie können jetzt Streams verwenden.

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

Um zu überprüfen , ob eine Reihe von int, doubleoder longeinen Wert enthält , Verwendung IntStream, DoubleStreamoder LongStreamjeweils.

Beispiel

int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);

87
Ich bin etwas neugierig auf die Leistung dieser Funktion im Vergleich zu den Suchfunktionen in der Arrays-Klasse im Vergleich zur Iteration über ein Array und der Verwendung einer equals () -Funktion oder == für Grundelemente.
Thomas Owens

186
Sie verlieren nicht viel, da asList () eine ArrayList zurückgibt, deren Herzstück ein Array ist. Der Konstruktor ändert nur eine Referenz, sodass dort nicht viel Arbeit zu erledigen ist. Und enthält () / indexOf () iteriert und verwendet equals (). Für Primitive sollten Sie es jedoch besser selbst codieren. Bei Strings oder anderen Klassen ist der Unterschied nicht erkennbar.
Joey

18
Seltsamerweise behauptet NetBeans, dass 'Arrays.asList (Feiertage)' für einen 'int [] Feiertag' eine 'Liste <int []>' und keine 'Liste <int>' zurückgibt. Es enthält nur ein einziges Element. Das heißt, der Inhalt funktioniert nicht, da er nur ein Element enthält. das int-Array.
Nyerguds

62
Nyerguds: In der Tat funktioniert dies nicht für Primitive. In Java können primitive Typen nicht generisch sein. asList wird als <T> List <T> asList (T ...) deklariert. Wenn Sie ein int [] übergeben, leitet der Compiler T = int [] ab, weil er nicht auf T = int schließen kann, weil Primitive nicht generisch sein können.
CromTheDestroyer

28
@Joey nur eine Randnotiz, es ist eine ArrayList, aber nicht java.util.ArrayListwie erwartet, die zurückgegebene reale Klasse ist: java.util.Arrays.ArrayList<E>definiert als : public class java.util.Arrays {private static class ArrayList<E> ... {}}.
TWiStErRob

362

Kurzes Update für Java SE 9

Referenzarrays sind schlecht. Für diesen Fall sind wir nach einem Satz. Seit Java SE 9 haben wir Set.of.

private static final Set<String> VALUES = Set.of(
    "AB","BC","CD","AE"
);

"Gibt es bei String s eine gute Möglichkeit zu testen, ob VALUES s enthält?"

VALUES.contains(s)

O (1).

Der richtige Typ , unveränderlich , O (1) und prägnant . Wunderschönen.*

Ursprüngliche Antwortdetails

Nur um den Code zu löschen. Wir haben (korrigiert):

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

Dies ist eine veränderbare statische Aufladung, von der FindBugs sagt, dass sie sehr ungezogen ist. Ändern Sie die Statik nicht und lassen Sie dies auch nicht von anderem Code zu. Das Feld sollte mindestens privat sein:

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

(Beachten Sie, dass Sie das new String[];Bit tatsächlich löschen können .)

Referenz-Arrays sind immer noch schlecht und wir wollen eine Menge:

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

(Paranoide Menschen wie ich fühlen sich möglicherweise wohler, wenn dies eingewickelt wird Collections.unmodifiableSet- es könnte dann sogar veröffentlicht werden.)

(* Um ein bisschen mehr über die Marke zu erfahren, fehlen in der Sammlungs-API voraussichtlich immer noch unveränderliche Sammlungstypen, und die Syntax ist für meinen Geschmack immer noch viel zu ausführlich.)


184
Außer es ist O (N), um die Sammlung überhaupt zu erstellen :)
Drew Noakes

61
Wenn es statisch ist, wird es wahrscheinlich einige Male verwendet. Die Zeit, die zum Initialisieren des Sets benötigt wird, hat also gute Chancen, im Vergleich zu den Kosten vieler linearer Suchvorgänge recht gering zu sein.
Xr.

1
Beim Erstellen wird die Sammlung dann von der Ladezeit des Codes dominiert (technisch gesehen O (n), aber praktisch konstant).
Tom Hawtin - Tackline

2
@ TomHawtin-Tackline Warum sagst du "gerade hier wollen wir ein Set"? Was ist in diesem Fall der Vorteil eines Sets (HashSet)? Warum ist ein "Referenzarray" schlecht (mit "Referenzarray" meinen Sie eine ArrayList, die von einem Array unterstützt wird, wie es durch einen Aufruf von generiert wurde Arrays.asList)?
Basil Bourque

6
@nmr A TreeSetwäre O(log n). HashSets sind so skaliert, dass die mittlere Anzahl von Elementen in einem Bucket ungefähr konstant ist. Zumindest für Arrays bis 2 ^ 30. Es kann beispielsweise Auswirkungen von Hardware-Caches geben, die von der Big-O-Analyse ignoriert werden. Nimmt auch an, dass die Hash-Funktion effektiv funktioniert.
Tom Hawtin - Tackline

206

Sie können ArrayUtils.containsvon Apache Commons Lang verwenden

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

Beachten Sie, dass diese Methode zurückgegeben wird, falsewenn das übergebene Array ist null.

Es gibt auch Methoden für primitive Arrays aller Art.

Beispiel:

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

if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
    // Do some stuff.
}

4
@ max4ever Ich stimme zu, aber das ist immer noch besser als "Rolling Your Own" und einfacher zu lesen als die rohe Java-Methode.
Jason


38
@ max4ever Manchmal ist diese Bibliothek bereits enthalten (aus anderen Gründen) und sie ist eine absolut gültige Antwort. Ich habe danach gesucht und bin bereits auf Apache Commons Lang angewiesen. Danke für diese Antwort.
GuiSim

1
Oder Sie können einfach die Methode kopieren (und eventuelle Abhängigkeiten).
Buffalo

10
@ max4ever Die meisten Android-Apps werden von Proguard minimiert und fügen nur die Klassen und Funktionen, die Sie benötigen, in Ihre App ein. Das macht es gleich, deine eigene zu rollen oder die Quelle der Apache-Sache zu kopieren. Und wer diese Minimalisierung nicht nutzt, muss sich nicht über 700kb oder 78kb beschweren :)
Kenyakorn Ketsombut

158

Einfach von Hand umsetzen:

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;
}

Verbesserung:

Die v != nullBedingung ist innerhalb der Methode konstant. Während des Methodenaufrufs wird immer der gleiche Boolesche Wert ausgewertet. Wenn die Eingabe arrayalso groß ist, ist es effizienter, diese Bedingung nur einmal auszuwerten, und wir können eine vereinfachte / schnellere Bedingung innerhalb der forSchleife basierend auf dem Ergebnis verwenden. Die verbesserte contains()Methode:

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;
}

9
@Phoexo Diese Lösung ist offensichtlich schneller, da die akzeptierte Antwort das Array in eine Liste einbindet und die Methode includes () in dieser Liste aufruft, während meine Lösung im Grunde das tut, was include () nur tun würde.
icza

10
@AlastorMoody e == v führt eine Referenzgleichheitsprüfung durch, die sehr schnell ist. Befindet sich dasselbe Objekt (dasselbe als Referenz) im Array, wird es schneller gefunden. Wenn es sich nicht um dieselbe Instanz handelt, ist sie möglicherweise immer noch dieselbe wie von der Methode equals () angegeben. Dies wird überprüft, wenn die Referenzen nicht identisch sind.
icza

20
Warum ist diese Funktion nicht Teil von Java? Kein Wunder, dass die Leute sagen, Java sei aufgebläht. Sehen Sie sich alle Antworten darüber an, die eine Reihe von Bibliotheken verwenden, wenn Sie nur eine for-Schleife benötigen. Kinder in diesen Tagen!
Phreakhead

4
@phreakhead Es ist Teil von Java, sieheCollection.contains(Object)
Steve Kuo

11
@icza Wenn Sie sich die Quelle von ansehen Arraysund ArrayListsich herausstellt, dass dies nicht unbedingt schneller ist als die verwendete Version Arrays.asList(...).contains(...). Der Aufwand für das Erstellen eines ArrayListist extrem gering und ArrayList.contains()verwendet eine intelligentere Schleife (tatsächlich werden zwei verschiedene Schleifen verwendet) als die oben gezeigte (JDK 7).
Axel

72

Vier verschiedene Möglichkeiten, um zu überprüfen, ob ein Array einen Wert enthält

1) Verwenden der Liste:

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

2) Verwenden von Set:

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

3) Verwenden einer einfachen Schleife:

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

4) Verwenden von Arrays.binarySearch ():

Der folgende Code ist falsch, der Vollständigkeit halber hier aufgeführt. binarySearch () kann NUR für sortierte Arrays verwendet werden. Sie werden feststellen, dass das Ergebnis unten seltsam ist. Dies ist die beste Option, wenn das Array sortiert ist.

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

Kurzes Beispiel:

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

5
Ihr Beispiel für eine binäre Suche sollte a> 0 zurückgeben.
Will Sherwood

6
Warum? Ich denke, es sollte ein> -1 zurückgeben, da 0 anzeigen würde, dass es am Kopf des Arrays enthalten ist.
Unten

1
Die erste Variante mit (a >= 0)war korrekt. Überprüfen Sie einfach die Dokumente . Sie sagen: "Beachten Sie, dass dies garantiert, dass der Rückgabewert genau dann> = 0 ist, wenn der Schlüssel gefunden wird."
Yoory N.

Warum funktioniert String und nicht Int? statischer Boolescher Wert existiert (int [] ints, int k) {return Arrays.asList (ints) .contains (k); }
Willians Martins

71

Wenn das Array nicht sortiert ist, müssen Sie alles durchlaufen und bei jedem einen Aufruf von equals durchführen.

Wenn das Array sortiert ist, können Sie eine binäre Suche durchführen, es gibt eine in der Arrays- Klasse.

Wenn Sie viele Mitgliedschaftsprüfungen durchführen möchten, möchten Sie im Allgemeinen möglicherweise alles in einem Set und nicht in einem Array speichern.


1
Wie ich in meiner Antwort sagte, können Sie, wenn Sie die Arrays-Klasse verwenden, das Array sortieren und dann die binäre Suche für das neu sortierte Array durchführen.
Thomas Owens

1
@ Thomas: Ich stimme zu. Oder Sie können einfach alles zu einem TreeSet hinzufügen. gleiche Komplexität. Ich würde die Arrays verwenden, wenn sie sich nicht ändern (vielleicht ein wenig Speicherlokalität sparen, da sich die Referenzen zusammenhängend befinden, obwohl die Zeichenfolgen dies nicht sind). Ich würde das Set verwenden, wenn sich dies im Laufe der Zeit ändern würde.
Uri

49

Für das, was es wert ist, habe ich einen Test durchgeführt, bei dem die 3 Vorschläge für die Geschwindigkeit verglichen wurden. Ich habe zufällige Ganzzahlen generiert, sie in einen String konvertiert und einem Array hinzugefügt. Ich suchte dann nach der höchstmöglichen Zahl / Zeichenfolge, was ein Worst-Case-Szenario für die wäre asList().contains().

Bei Verwendung einer 10K-Arraygröße waren die Ergebnisse:

Sortieren & Suchen: 15
Binäre Suche: 0
asList.contains: 0

Bei Verwendung eines 100K-Arrays waren die Ergebnisse:

Sortieren & Suchen: 156
Binäre Suche: 0
asList.contains: 32

Wenn das Array also in sortierter Reihenfolge erstellt wird, ist die binäre Suche am schnellsten, andernfalls asList().containswäre dies der richtige Weg. Wenn Sie viele Suchvorgänge haben, kann es sinnvoll sein, das Array zu sortieren, damit Sie die binäre Suche verwenden können. Es hängt alles von Ihrer Anwendung ab.

Ich würde denken, das sind die Ergebnisse, die die meisten Leute erwarten würden. Hier ist der Testcode:

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));
    }
}

6
Ich verstehe diesen Code nicht. Sie sortieren die Array-Zeichenfolgen und verwenden in beiden Aufrufen von binarySearch dasselbe (sortierte) Array. Wie kann das etwas anderes als die HotSpot-Laufzeitoptimierung anzeigen? Das gleiche gilt für den Aufruf asList.contains. Sie erstellen eine Liste aus dem sortierten Array und enthalten daraufhin den höchsten Wert. Natürlich wird es einige Zeit dauern. Was bedeutet dieser Test? Ganz zu schweigen davon, dass es sich um ein falsch geschriebenes Mikrobenchmark handelt
Erik

Da die binäre Suche nur auf eine sortierte Menge angewendet werden kann, ist Sortieren und Suchen die einzig mögliche Möglichkeit, die binäre Suche zu verwenden.
Erik

Die Sortierung wurde möglicherweise bereits aus einer Reihe anderer Gründe durchgeführt, z. B. könnte sie nach init sortiert und nie geändert werden. Es ist sinnvoll, die Suchzeit selbst zu testen. Dies ist jedoch ein weniger als herausragendes Beispiel für Mikrobenchmarking. Microbenchmarks sind in Java bekanntermaßen schwer zu finden und sollten beispielsweise die Ausführung des Testcodes umfassen, um eine Hotspot-Optimierung zu erhalten, bevor der eigentliche Test ausgeführt wird, geschweige denn, dass der tatsächliche Testcode mehr als EINMAL mit einem Timer ausgeführt wird. Beispiel Fallstricke
Thor84no

7
Dieser Test ist fehlerhaft, da alle drei Tests in derselben JVM-Instanz ausgeführt werden. Die späteren Tests könnten von den früheren Tests profitieren, die den Cache, die JIT usw. aufwärmen
Steve Kuo

4
Dieser Test ist eigentlich völlig unabhängig. Sortieren & Suchen ist linearithmisch (n * log (n)), binäre Suche logarithmisch und ArrayUtils.contains ist offensichtlich linear. Es macht keinen Sinn, diese Lösungen zu vergleichen, da sie sich in völlig unterschiedlichen Komplexitätsklassen befinden.
Dragn

37

Anstatt auch die Syntax für die schnelle Array-Initialisierung zu verwenden, können Sie sie auf ähnliche Weise sofort mit der Methode Arrays.asList als Liste initialisieren, z.

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

Dann können Sie (wie oben) tun:

STRINGS.contains("the string you want to find");

35

Mit Java 8 können Sie einen Stream erstellen und prüfen, ob Einträge im Stream übereinstimmen "s":

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

Oder als generische Methode:

public static <T> boolean arrayContains(T[] array, T value) {
    return Arrays.stream(array).anyMatch(value::equals);
}

3
Beachten Sie auch die primitiven Spezialisierungen.
Skiwi

Um dies hinzuzufügen, gibt anyMatchJavaDoc an, dass dies der Fall ist "...May not evaluate the predicate on all elements if not necessary for determining the result.", sodass die Verarbeitung nach dem Finden einer Übereinstimmung möglicherweise nicht fortgesetzt werden muss.
mkobit

28

Mit der Arrays-Klasse können Sie eine binäre Suche nach dem Wert durchführen. Wenn Ihr Array nicht sortiert ist, müssen Sie die Sortierfunktionen in derselben Klasse verwenden, um das Array zu sortieren, und es dann durchsuchen.


Sie können die Sortierfunktionen in derselben Klasse verwenden, um dies zu erreichen ... Ich sollte das meiner Antwort hinzufügen.
Thomas Owens

1
Wird wahrscheinlich mehr kosten als der Ansatz asList (). Inclains (), denke ich. Es sei denn, Sie müssen dies sehr oft überprüfen (aber wenn es sich nur um eine statische Liste von Werten handelt, die zunächst sortiert werden können, um fair zu sein).
Joey

Wahr. Es gibt viele Variablen, welche am effektivsten wären. Es ist jedoch gut, Optionen zu haben.
Thomas Owens

Einige Code, der dies hier tut: stackoverflow.com/a/48242328/9131078
OOBalance

Das Sortieren eines ganzen Arrays zum Zweck einer Suche ist teuer. Wir können dieselbe CPU-Zeit für die Linersuche selbst verwenden. Ich bevorzuge die binäre Suche in einer Sammlung, die bereits zuvor in sortierter Reihenfolge erstellt wurde.
Arunwithasmile

17

ObStupidAnswer (aber ich denke, hier gibt es irgendwo eine Lektion):

enum Values {
    AB, BC, CD, AE
}

try {
    Values.valueOf(s);
    return true;
} catch (IllegalArgumentException exc) {
    return false;
}

1
Das Werfen von Ausnahmen ist anscheinend schwer, aber dies wäre eine neuartige Methode, um einen Wert zu testen, wenn er funktioniert. Der Nachteil ist, dass die Aufzählung vorher definiert werden muss.
James P.

13

Wenn Sie HashSet <String> verwenden, wie von Tom Hawtin vorgeschlagen, müssen Sie sich keine Gedanken über das Sortieren machen, und Ihre Geschwindigkeit ist dieselbe wie bei der binären Suche in einem vorsortierten Array, wahrscheinlich sogar noch schneller.

Es hängt natürlich alles davon ab, wie Ihr Code eingerichtet ist, aber von meinem Standpunkt aus wäre die Reihenfolge:

Auf einem unsortierten Array:

  1. HashSet
  2. asList
  3. sort & binär

Auf einem sortierten Array:

  1. HashSet
  2. Binär
  3. asList

Also so oder so, HashSet für den Sieg.


2
Die HashSet-Mitgliedschaft sollte O (1) sein und die binäre Suche in einer sortierten Sammlung ist O (log n).
Skylar Saveland

11

Wenn Sie über die Google-Sammlungsbibliothek verfügen, kann Toms Antwort mithilfe von ImmutableSet (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html) erheblich vereinfacht werden.

Dies beseitigt wirklich viel Unordnung bei der vorgeschlagenen Initialisierung

private static final Set<String> VALUES =  ImmutableSet.of("AB","BC","CD","AE");

10

Eine mögliche Lösung:

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");
      }
  }
}

8

Entwickler tun oft:

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

Der obige Code funktioniert, es ist jedoch nicht erforderlich, eine Liste zu konvertieren, um sie zuerst festzulegen. Das Konvertieren einer Liste in einen Satz erfordert zusätzliche Zeit. Es kann so einfach sein wie:

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

oder

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

return false;

Der erste ist besser lesbar als der zweite.


7

Die Verwendung einer einfachen Schleife ist der effizienteste Weg, dies zu tun.

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

Mit freundlicher Genehmigung von Programcreek


Dies löst eine Nullzeigerausnahme aus, wenn das Array eine Nullreferenz vor dem Zielwert enthält.
Samuel Edwin Ward

1
Die if-Anweisung sollte lauten: if (targetValue.equals (s)), da String equals eine Prüferinstanz hat.
TheArchon

Verwenden Sie stattdessen Objects.equals (obj1, obj2), um null sicher zu sein.
Trilogie

7

Verwenden Sie in Java 8 Streams.

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);

7
Gibt es irgendwelche Vorteile bei diesem Ansatz?
Johannes Stadler

1
Es beantwortet die Frage nicht.
Florian F

5
  1. Verwenden Sie für Arrays mit begrenzter Länge Folgendes (wie von camickr angegeben ). Dies ist bei wiederholten Überprüfungen langsam, insbesondere bei längeren Arrays (lineare Suche).

     Arrays.asList(...).contains(...)
  2. Für eine schnelle Leistung, wenn Sie wiederholt mit einem größeren Satz von Elementen vergleichen

    • Ein Array ist die falsche Struktur. Verwenden Sie a TreeSetund fügen Sie jedes Element hinzu. Es sortiert Elemente und hat eine schnelle exist()Methode (binäre Suche).

    • Wenn die Elemente implementiert werden Comparableund Sie möchten, dass die entsprechend TreeSetsortiert werden:

      ElementClass.compareTo()Methode muss kompatibel sein mit ElementClass.equals(): Siehe Triaden, die nicht zum Kampf erscheinen? (Java Set fehlt ein Element)

      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));
    • Verwenden Sie andernfalls Ihre eigenen 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);
    • Die Auszahlung: Überprüfen Sie die Existenz eines Elements:

      // Fast binary search through sorted elements (performance ~ log(size)):
      boolean containsElement = myElements.exists(someElement);

4
Warum sich damit beschäftigen TreeSet? HashSetist schneller (O (1)) und erfordert keine Bestellung.
Sean Owen

4

Versuche dies:

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");
}

4

Verwenden Sie Folgendes (die contains()Methode befindet sich ArrayUtils.in()in diesem Code):

ObjectUtils.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 ;
    }

}

Wie Sie im obigen Code, dass es andere Utility - Methoden sehen ObjectUtils.equals()und ArrayUtils.indexOf(), die an anderen Orten verwendet wurden als gut.


Ich bin sehr spät dran, um an dieser Diskussion teilzunehmen, aber da mein Ansatz zur Lösung dieses Problems, als ich vor einigen Jahren damit konfrontiert wurde, etwas anders war als die anderen Antworten, die hier bereits veröffentlicht wurden, veröffentliche ich die Lösung, die ich damals verwendet habe. hier, falls es jemand nützlich findet.
Abhishek Oza

3

Überprüfen Sie dies

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
Dies funktioniert nicht - es wird elsefür jeden eingegeben Element , das nicht übereinstimmt (wenn Sie also in diesem Array nach "AB" suchen, wird es dreimal dorthin gehen, da 3 der Werte nicht "AB" sind ").
Bernhard Barker

3

Arrays.asList () -> dann funktioniert das Aufrufen der Methode includes () immer, aber ein Suchalgorithmus ist viel besser, da Sie keinen einfachen Listen-Wrapper um das Array erstellen müssen, wie es Arrays.asList () tut .

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.
}

Arrays.asListist nicht O (n). Es ist nur eine leichte Hülle. Schauen Sie sich die Implementierung an.
Patrick Parker

3

Wenn Sie nicht möchten, dass zwischen Groß- und Kleinschreibung unterschieden wird

Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);

2

Verwenden Sie diese Array.BinarySearch(array,obj)Option, um das angegebene Objekt im Array zu finden oder nicht.

Beispiel:

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

false - existiert nicht


4
Array.BinarySearchund Array.FindIndexsind .NET-Methoden und existieren in Java nicht.
Ataylor

@ataylor gibt es Arrays.binarySearch in Java. Aber du hast recht, kein Arrays.findIndex
mente

Es sollte beachtet werden:The array must be sorted prior to making this call. If it is not sorted, the results are undefined.
Dorian Gray

1

Erstellen Sie einen Booleschen Wert, der anfänglich auf false gesetzt ist. Führen Sie eine Schleife aus, um jeden Wert im Array zu überprüfen und mit dem Wert zu vergleichen, gegen den Sie prüfen. Wenn Sie jemals eine Übereinstimmung erhalten, setzen Sie den Booleschen Wert auf true und beenden Sie die Schleife. Dann behaupten Sie, dass der Boolesche Wert wahr ist.


1

Versuchen Sie es mit der Java 8-Prädikattestmethode

Hier ist ein vollständiges Beispiel dafür.

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Test {
 public static final List<String> VALUES = Arrays.asList("AA", "AB", "BC", "CD", "AE");

 public static void main(String args[]) {
  Predicate<String> containsLetterA = VALUES -> VALUES.contains("AB");
  for (String i : VALUES) {

   System.out.println(containsLetterA.test(i));
  } 
 }
}

http://mytechnologythought.blogspot.com/2019/10/java-8-predicate-test-method-example.html

https://github.com/VipulGulhane1/java8/blob/master/Test.java


0

Die Verwendung von a Spliterator verhindert die unnötige Erzeugung von a List

boolean found = false;  // class variable

String search = "AB";
Spliterator<String> spl = Arrays.spliterator( VALUES, 0, VALUES.length );
while( (! found) && spl.tryAdvance(o -> found = o.equals( search )) );

found == trueif searchist im Array enthalten


Dies funktioniert für Arrays von Grundelementen

public static final int[] VALUES = new int[] {1, 2, 3, 4};
boolean found = false;  // class variable

int search = 2;
Spliterator<Integer> spl = Arrays.spliterator( VALUES, 0, VALUES.length );


-2

Sie können dies auf zwei Arten überprüfen

A) Konvertieren Sie das Array in eine Zeichenfolge und überprüfen Sie die erforderliche Zeichenfolge mit der Methode .contains

 String a=Arrays.toString(VALUES);
    System.out.println(a.contains("AB"));
    System.out.println(a.contains("BC"));
    System.out.println(a.contains("CD"));
    System.out.println(a.contains("AE"));

B) Dies ist eine effizientere Methode

 Scanner s=new Scanner(System.in);


   String u=s.next();
   boolean d=true;
    for(int i=0;i<VAL.length;i++)
    {
        if(VAL[i].equals(u)==d)
            System.out.println(VAL[i] +" "+u+VAL[i].equals(u));  

    }

1
Die String-Konvertierung ist absurd ineffizient und die Lösung ist falsch, zB enthält (",") true.
Atuos
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.