Вопрос: Как проверить, содержит ли массив определенное значение?


у меня есть String[]с такими значениями:

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

Данный String s, есть ли хороший способ проверить, VALUESсодержит s?


1822


источник


Ответы:


Arrays.asList(yourArray).contains(yourValue)

Предупреждение: это не работает для массивов примитивов (см. Комментарии).


поскольку

Теперь вы можете использовать Streamчтобы проверить, существует ли массив int, doubleили longсодержит значение (соответственно используя IntStream, DoubleStreamили LongStream)

пример

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

2381



Просто, чтобы очистить код до начала. У нас (исправлено):

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

Это изменчивая статика, которую FindBugs скажет вам, очень озорной. Он должен быть закрытым:

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

(Обратите внимание: на самом деле вы можете new String[];немного.)

Итак, ссылочные массивы плохие, и, в частности, здесь нам нужен набор:

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

(Параноидальные люди, такие как я, могут чувствовать себя более непринужденно, если это было завернуто в Collections.unmodifiableSet- его можно даже обнародовать).

«Учитывая String s, есть ли хороший способ проверить, содержит ли VALUES?»

VALUES.contains(s)

O (1).


302



Вы можете использовать ArrayUtils.containsиз Apache Commons Lang

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

Обратите внимание, что этот метод возвращает falseесли переданный массив null,

Существуют также методы, доступные для примитивных массивов всех видов.

Пример:

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

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

168



Я удивлен, что никто не предложил просто реализовать его вручную:

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

Улучшение:

v != nullусловие является постоянным внутри метода, оно всегда вычисляет одно и то же логическое значение во время вызова метода. Поэтому, если вход arrayявляется большим, более эффективно оценивать это условие только один раз, и мы можем использовать упрощенное / более быстрое условие внутри forна основе результата. Улучшенный 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;
}

136



If the array is not sorted, you will have to iterate over everything and make a call to equals on each.

If the array is sorted, you can do a binary search, there's one in the Arrays class.

Generally speaking, if you are going to do a lot of membership checks, you may want to store everything in a Set, not in an array.


65



Four Different Ways to Check If an Array Contains a Value

1) Using List:

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

2) Using Set:

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

3) Using a simple loop:

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

4) Using Arrays.binarySearch():

The code below is wrong, it is listed here for completeness. binarySearch() can ONLY be used on sorted arrays. You will find the result is weird below. This is the best option when array is sorted.

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

Quick Example:

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

56



For what its worth I ran a test comparing the 3 suggestions for speed. I generated random integers, converted them to a String and added them to an array. I then searched for the highest possible number/string, which would be a worst case scenario for the asList().contains().

When using a 10K array size the results where:

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

When using a 100K array the results where:

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

So if the array is created in sorted order the binary search is the fastest, otherwise the asList().contains would be the way to go. If you have many searches, then it may be worthwhile to sort the array so you can use the binary search. It all depends on your application.

I would think those are the results most people would expect. Here is the test code:

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



Instead of using the quick array initialsation syntax to you could just initialise it as a List straight away in a similar manner using the Arrays.asList method e.g.:

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

Then you can do (like above): STRINGS.contains("the string you want to find");


29



With Java 8 you can create a stream and check if any entries in the stream matches "s":

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

Or as a generic method:

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

29



You can use the Arrays class to perform a binary search for the value. If your array is not sorted, you will have to use the sort functions in the same class to sort the array, then search through it.


22