27

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

14

У меня есть массив строк типа String[] со значениями, например:

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

Как мне проверить, содержится ли строка s в массиве VALUES? Есть ли эффективный способ сделать это?

3 ответ(ов)

1

На StackOverflow.com вопрос можно было бы ответить следующим образом:


В вашем коде метод contains выполняет поиск элемента в массиве, и я заметил, что можно оптимизировать его. Давайте рассмотрим ваш оригинальный код:

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 повторяется для каждого элемента массива, что может быть неэффективно, особенно если массив большой. Вместо этого мы можем выполнить проверку на null один раз, а затем использовать упрощённое условие внутри цикла.

Вот как может выглядеть улучшенный метод contains2:

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

В этом варианте, если v равно null, мы просто ищем null в массиве. Если v не null, мы проверяем его на равенство с элементами массива. Это позволяет избежать избыточных проверок и делает метод более эффективным.

Если у вас есть дополнительные вопросы или нужно больше пояснений, не стесняйтесь спрашивать!

0

Для того, чтобы прояснить ситуацию, я провёл тест, сравнивающий три предложенных метода по скорости. Я генерировал случайные целые числа, конвертировал их в строки и добавлял в массив. Затем я искал наибольший возможный номер/строку, что представляло собой худший сценарий для метода asList().contains().

При размере массива 10K результаты были следующими:

Сортировка и поиск : 15 мс
Бинарный поиск     : 0 мс
asList.contains    : 0 мс

При размере массива 100K результаты были следующими:

Сортировка и поиск : 156 мс
Бинарный поиск     : 0 мс
asList.contains    : 32 мс

Таким образом, если массив создаётся в отсортированном порядке, бинарный поиск оказывается самым быстрым. В противном случае, метод asList().contains будет более подходящим. Если у вас много поисков, имеет смысл отсортировать массив, чтобы использовать бинарный поиск. Всё зависит от вашей задачи.

Я думаю, что такие результаты были бы ожидаемы для большинства. Вот код теста:

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("Сортировка и поиск : "
                + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(Arrays.binarySearch(strings, "" + (size - 1)));
        System.out.println("Поиск        : "
                + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(Arrays.asList(strings).contains("" + (size - 1)));
        System.out.println("Содержит      : "
                + (System.currentTimeMillis() - start));
    }
}
0

С помощью Java 8 вы можете создать стрим и проверить, есть ли в нем какое-либо значение, соответствующее строке "s":

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

Также можно создать универсальный метод:

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

Этот метод принимает массив и значение, и возвращает true, если значение содержится в массиве.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь