Vraag Hoe kan ik testen of een array een bepaalde waarde bevat?


ik heb een String[] met waarden zoals:

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

Gegeven String s, is er een goede manier om te testen of VALUES bevat s?


1850
2017-07-15 00:03


oorsprong


antwoorden:


Arrays.asList(yourArray).contains(yourValue)

Waarschuwing: dit werkt niet voor arrays van primitieven (zie de opmerkingen).


Sinds

U kunt nu een Stream om te controleren of een array van int, double of long bevat een waarde (door het gebruik van een IntStream, DoubleStream of LongStream)

Voorbeeld

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

2423
2017-07-15 00:04



Gewoon om de code te wissen om mee te beginnen. We hebben (gecorrigeerd):

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

Dit is een veranderlijke static die FindBugs je zal vertellen is erg ondeugend. Het moet privé zijn:

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

(Let op, je kunt het new String[]; beetje.)

Dus referentie-arrays zijn slecht, en in het bijzonder hier willen we een set:

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

(Paranoïde mensen, zoals ikzelf, kunnen zich meer op hun gemak voelen als dit is ingepakt Collections.unmodifiableSet - het kan zelfs openbaar worden gemaakt.)

"Gegeven String s, is er een goede manier om te testen of VALUES s bevat?"

VALUES.contains(s)

O (1).


309
2017-07-15 01:13



Je kunt gebruiken ArrayUtils.contains van Apache Commons Lang

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

Merk op dat deze methode terugkeert false als de doorgegeven array is null.

Er zijn ook methoden beschikbaar voor primitieve arrays van alle soorten.

Voorbeeld:

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

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

171
2018-05-31 13:17



Het verbaast me dat niemand heeft voorgesteld om het eenvoudig met de hand uit te voeren:

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

Verbetering:

De v != null voorwaarde is constant binnen de methode, het evalueert altijd naar dezelfde Booleaanse waarde tijdens de aanroep van de methode. Dus als de input array is groot, het is efficiënter om deze conditie slechts één keer te evalueren en we kunnen een vereenvoudigde / snellere conditie gebruiken binnen de for loop op basis van het resultaat. De verbeterde 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



Als de array niet is gesorteerd, moet je alles herhalen en een oproep tot gelijken maken voor elke array.

Als de array is gesorteerd, kunt u een binaire zoekopdracht uitvoeren, er is er een in de arrays klasse.

Over het algemeen kunt u, als u veel lidmaatschapscontroles gaat uitvoeren, alles in een set opslaan, niet in een array.


65
2017-07-15 00:05



Vier verschillende manieren om te controleren of een array een waarde bevat

1) Lijst gebruiken:

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

2) Set gebruiken:

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

3) Gebruik een eenvoudige lus:

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

4) Arrays.binarySearch () gebruiken:

De onderstaande code is verkeerd, deze staat hier voor de volledigheid. binarySearch () kan ALLEEN worden gebruikt op gesorteerde arrays. U zult merken dat het resultaat hieronder raar is. Dit is de beste optie wanneer array is gesorteerd.

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

Snel voorbeeld:

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



Voor wat het waard is, heb ik een test uitgevoerd waarin de 3 suggesties voor snelheid werden vergeleken. Ik heb willekeurige gehele getallen gegenereerd, deze geconverteerd naar een tekenreeks en aan een array toegevoegd. Ik zocht toen naar het hoogst mogelijke aantal / string, wat een slechtste scenario zou zijn voor de asList (). Contains ().

Bij gebruik van een 10K-arraygrootte de resultaten waarbij:

Sorteren & Zoeken: 15
Binaire zoekopdracht: 0
asList.contains: 0

Bij gebruik van een 100K-array de resultaten waarbij:

Sorteren en zoeken: 156
Binaire zoekopdracht: 0
asList.contains: 32

Dus als de array in gesorteerde volgorde wordt gemaakt, is de binaire zoekopdracht de snelste, anders is de asList (). Als u veel zoekopdrachten uitvoert, is het wellicht de moeite waard om de array te sorteren, zodat u de binaire zoekopdracht kunt gebruiken. Het hangt allemaal af van uw toepassing.

Ik denk dat dit de resultaten zijn die de meeste mensen zouden verwachten. Hier is de 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