Frage Wie kann ich testen, ob ein Array einen bestimmten Wert enthält?


Ich habe ein String[] mit Werten wie:

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

Gegeben String sGibt es eine gute Möglichkeit zu testen, ob VALUES enthält s?


1850
2017-07-15 00:03


Ursprung


Antworten:


Arrays.asList(yourArray).contains(yourValue)

Achtung: Dies funktioniert nicht für Arrays von Primitiven (siehe Kommentare).


Schon seit

Sie können jetzt ein Stream um zu prüfen, ob ein Array von int, double oder long enthält einen Wert (durch Verwendung von a IntStream, DoubleStream oder LongStream)

Beispiel

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

2423
2017-07-15 00:04



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 Situation, die FindBugs Ihnen sagen wird, dass sie sehr ungezogen ist. Es sollte privat sein:

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

(Beachten Sie, dass Sie die new String[]; Bit.)

Also, Referenz-Arrays sind schlecht, und hier wollen wir eine Menge:

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

(Paranoide, wie ich, fühlen sich vielleicht wohler, wenn sie eingewickelt sind.) Collections.unmodifiableSet - Es könnte sogar öffentlich gemacht werden.)

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

VALUES.contains(s)

O (1).


309
2017-07-15 01:13



Sie können verwenden ArrayUtils.contains von Apache Commons Lang

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

Beachten Sie, dass diese Methode zurückgibt false wenn 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.
}

171
2018-05-31 13:17



Ich bin überrascht, dass niemand vorgeschlagen hat, es einfach von Hand zu implementieren:

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:

Das v != null Bedingung ist innerhalb der Methode konstant, sie wertet während des Methodenaufrufs immer den gleichen booleschen Wert aus. Also, wenn die Eingabe array ist groß, es ist effizienter, diese Bedingung nur einmal zu bewerten, und wir können eine vereinfachte / schnellere Bedingung innerhalb der benutzen for Schleife basierend auf dem Ergebnis. Das verbessert 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;
}

142
2017-09-28 07:45



Wenn das Array nicht sortiert ist, müssen Sie über alles hinweg iterieren und einen Aufruf an Gleichgestellte vornehmen.

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 Sie im Allgemeinen alles in einem Set und nicht in einem Array speichern.


65
2017-07-15 00:05



Vier verschiedene Möglichkeiten zu prü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, er ist hier der Vollständigkeit halber aufgeführt. binarySearch () kann NUR für sortierte Arrays verwendet werden. Sie werden das Ergebnis unten seltsam finden. 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;
        }

Schnelles 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

59
2018-05-07 19:14



Für was es wert ist, führte ich einen Test durch, der die 3 Vorschläge für Geschwindigkeit vergleicht. Ich generierte zufällige Ganzzahlen, konvertierte sie in einen String und fügte sie einem Array hinzu. Ich suchte dann nach der höchstmöglichen Zahl / Zeichenfolge, was ein Worst-Case-Szenario für die asList (). Contains () wäre.

Wenn Sie eine 10K-Array-Größe verwenden, lauten die Ergebnisse:

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

Wenn Sie ein 100K Array verwenden, waren die Ergebnisse:

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

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

Ich denke, das sind die Ergebnisse, die die meisten Menschen 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));
    }
}

46
2017-07-15 01:28