2717 Stimmen

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

Ich habe eine String[] mit Werten wie diesen:

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

Gegeben String s Gibt es eine gute Methode, um zu testen, ob VALUES enthält s ?

6 Stimmen

Das ist ein langer Weg, aber Sie können eine for-Schleife verwenden: "for (String s : VALUES) if (s.equals("MYVALUE")) return true;

1 Stimmen

Ja, es war mir fast peinlich, die Frage zu stellen, aber gleichzeitig war ich überrascht, dass sie noch nicht gestellt worden war. Es ist eine dieser APIs, mit denen ich einfach noch nicht in Berührung gekommen bin...

3 Stimmen

@camickr - ich habe eine fast identische Situation mit diesem hier: stackoverflow.com/a/223929/12943 Es wird immer wieder abgestimmt, obwohl es nur ein Copy/Paste aus der Sun-Dokumentation war. Ich schätze, die Bewertung basiert darauf, wie viel Hilfe man geleistet hat und nicht darauf, wie viel Mühe man sich gegeben hat - und vor allem darauf, wie schnell man es veröffentlicht hat! Vielleicht sind wir auf das Geheimnis von John Skeet gestoßen! Nun, gute Antwort, +1 für Sie.

3386voto

camickr Punkte 315810
Arrays.asList(yourArray).contains(yourValue)

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


Desde java-8 können Sie jetzt Streams verwenden.

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

Um zu prüfen, ob ein Array von int , double o long enthält einen Wert Verwendung IntStream , DoubleStream o LongStream beziehungsweise.

Beispiel

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

112 Stimmen

Ich bin etwas neugierig auf die Leistung dieser im Vergleich zu den Suchfunktionen in der Klasse Arrays versus Iteration über ein Array und mit einem equals() Funktion oder == für Primitive.

3 Stimmen

Beide würden eine lineare Suche darstellen.

0 Stimmen

@Thomas: Ich denke, dass asList() tatsächlich ein neues Objekt zuweisen könnte, das an das vorhandene Array delegiert, so dass Sie die Zuweisungskosten bezahlen. Die Liste wird durch das Array unterstützt, so dass die Elemente selbst nicht neu zugewiesen werden sollten.

452voto

Tom Hawtin - tackline Punkte 142461

Kurzes Update für Java SE 9

Referenz-Arrays sind schlecht. In diesem Fall suchen wir eine Menge. Seit Java SE 9 haben wir Set.of .

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

"Gibt es bei einer Zeichenkette s eine gute Möglichkeit zu prüfen, ob VALUES s enthält?"

VALUES.contains(s)

O(1).

Le site richtige Art , unveränderlich , O(1) y kurz und bündig . Schön.*

Details der Originalantwort

Nur um den Code zunächst einmal zu klären. Wir haben (korrigiert):

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

Dies ist ein veränderbares statisches Element, das FindBugs als sehr unanständig bezeichnen wird. Ändern Sie keine Statics und erlauben Sie anderen Code nicht, dies ebenfalls zu tun. Als absolutes Minimum sollte das Feld privat sein:

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

(Hinweis: Sie können die new String[]; bit.)

Referenz-Arrays sind immer noch schlecht, und wir wollen einen Satz:

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

(Paranoide Menschen, wie ich selbst, würden sich vielleicht wohler fühlen, wenn dies in Collections.unmodifiableSet - sie könnte dann sogar veröffentlicht werden).

(*Um ein wenig mehr auf der Höhe der Zeit zu sein, die Sammlungen API ist vorhersehbar immer noch fehlen unveränderliche Sammlungstypen und die Syntax ist immer noch viel zu langatmig, für meinen Geschmack).

202 Stimmen

Außer dass es O(N) ist, die Sammlung überhaupt erst zu erstellen :)

69 Stimmen

Wenn sie statisch ist, wird sie wahrscheinlich ziemlich oft benutzt werden. Der Zeitaufwand für die Initialisierung der Menge ist also im Vergleich zu den Kosten für eine Vielzahl von linearen Suchvorgängen sehr gering.

1 Stimmen

Die Erstellung der Sammlung wird dann von der Ladezeit des Codes dominiert (die technisch gesehen O(n) ist, aber praktisch konstant).

243voto

Intracer Punkte 2839

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

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

Beachten Sie, dass diese Methode Folgendes zurückgibt false wenn das übergebene Array null .

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

Ejemplo:

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

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

4 Stimmen

@max4ever Ich stimme zu, aber das ist immer noch besser als "Rolling your own" und einfacher zu lesen als der rohe Java-Weg.

2 Stimmen

46 Stimmen

@max4ever Manchmal haben Sie diese Bibliothek bereits integriert (aus anderen Gründen) und es ist eine vollkommen gültige Antwort. Ich habe danach gesucht und bin bereits auf Apache Commons Lang angewiesen. Vielen Dank für diese Antwort.

167voto

icza Punkte 335148

Führen Sie es einfach von Hand aus:

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:

Le site v != null Bedingung innerhalb der Methode konstant ist. Sie wird während des Methodenaufrufs immer auf denselben booleschen Wert ausgewertet. Wenn also die Eingabe array groß ist, ist es effizienter, diese Bedingung nur einmal auszuwerten, und wir können eine vereinfachte/schnellere Bedingung innerhalb der for Schleife auf der Grundlage des Ergebnisses. 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;
}

1 Stimmen

Wie groß wäre der Leistungsunterschied zwischen dieser Lösung und der akzeptierten Antwort?

9 Stimmen

@Phoexo Diese Lösung ist offensichtlich schneller, weil die akzeptierte Antwort das Array in eine Liste umwandelt und die Methode contains() für diese Liste aufruft, während meine Lösung im Grunde das tut, was contains() nur tun würde.

1 Stimmen

E == v || v != null && v.equals( e ) --- Der erste Teil der OR-Anweisung vergleicht e und v. Der zweite Teil tut dasselbe (nachdem er überprüft hat, dass v nicht null ist). Warum sollte man eine solche Implementierung haben, anstatt nur (e==v). Können Sie mir das erklären?

97voto

Sireesh Yarlagadda Punkte 11586

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

  1. Verwendung von List :

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

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

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

    Der unten stehende Code ist falsch, er wird hier nur der Vollständigkeit halber aufgeführt. binarySearch() kann NUR für sortierte Arrays verwendet werden. Das Ergebnis finden Sie weiter unten. Dies ist die beste Option, wenn das Feld sortiert ist.

    public static boolean binarySearch(String[] arr, String targetValue) {  
        return Arrays.binarySearch(arr, targetValue) >= 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

5 Stimmen

Ihr Beispiel für die binäre Suche sollte a > 0 ergeben;

7 Stimmen

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

3 Stimmen

Die erste Variante mit (a >= 0) richtig war, überprüfen Sie einfach die Dokumente Sie sagen: "Beachten Sie, dass dies garantiert, dass der Rückgabewert >= 0 ist, wenn und nur wenn der Schlüssel gefunden wird".

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X