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

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

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

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

+2058
15 июл. '09 в 0:03
источник поделиться
27 ответов
Arrays.asList(yourArray).contains(yourValue)

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


Начиная с вы можете использовать Streams.

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

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

пример

int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
+2663
15 июл. '09 в 0:04
источник

Связанные вопросы


Похожие вопросы

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

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 - это могло бы даже быть обнародовано.)

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

VALUES.contains(s)

O (1).

Обновление: Начиная с Java SE 9 у нас есть Set.of

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

Правильный тип, неизменный, O (1) и краткий. Красивая.

(Чтобы немного больше рассказать о бренде, API коллекций, как и следовало ожидать, по-прежнему не содержит неизменяемых типов коллекций, а синтаксис все еще слишком многословен, на мой вкус.)

+326
15 июл. '09 в 1:13
источник

Вы можете использовать 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.
}
+186
31 мая '11 в 13:17
источник

Просто выполните это вручную:

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;
}
+149
28 сент. '12 в 7:45
источник

Если массив не отсортирован, вам придется перебирать все и делать вызов равным для каждого.

Если массив отсортирован, вы можете выполнить двоичный поиск, там один в классе Arrays.

Вообще говоря, если вы собираетесь выполнять много проверок членства, вы можете захотеть сохранить все в наборе, а не в массиве.

+67
15 июл. '09 в 0:05
источник

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

1) Использование списка:

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

2) Использование Set:

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

3) Используя простой цикл:

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

4) Использование Arrays.binarySearch():

Код ниже неверен, он указан здесь для полноты. binarySearch() может ТОЛЬКО использоваться на отсортированных массивах. Вы увидите, что результат ниже. Это лучший вариант при сортировке массива.

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

Быстрый пример:

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
+64
07 мая '14 в 19:14
источник

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

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

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

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

Sort & Search   : 156
Binary Search   : 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("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));
    }
}
+47
15 июл. '09 в 1:28
источник

С 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);
}
+33
13 мар. '14 в 14:53
источник

Вместо того, чтобы использовать синтаксис быстрой инициализации массива, вы можете просто инициализировать его в виде списка List сразу же, используя метод Arrays.asList, например:

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

Тогда вы можете сделать (как выше):

STRINGS.contains("the string you want to find");
+32
20 янв. '11 в 13:58
источник

Вы можете использовать класс Arrays для выполнения двоичного поиска значения. Если ваш массив не отсортирован, вам придется использовать функции сортировки в том же классе, чтобы отсортировать массив, а затем выполнить поиск по нему.

+25
15 июл. '09 в 0:05
источник

ObStupidAnswer (но я думаю, что там где-то есть урок):

enum Values {
    AB, BC, CD, AE
}

try {
    Values.valueOf(s);
    return true;
} catch (IllegalArgumentException exc) {
    return false;
}
+16
15 июл. '09 в 1:18
источник

На самом деле, если вы используете HashSet <String>, как предложил Том Хоутин, вам не нужно беспокоиться о сортировке, и ваша скорость такая же, как и при бинарном поиске в предварительно отсортированном массиве, возможно, даже быстрее.

Очевидно, все зависит от того, как настроен ваш код, но с того места, где я стою, порядок будет следующим:

На несортированном массиве:

  1. HashSet
  2. asList
  3. сортировать и двоичные

В отсортированном массиве:

  1. HashSet
  2. двоичный
  3. asList

Так или иначе, HashSet для победы.

+12
11 июн. '10 в 2:37
источник

Если у вас есть библиотека коллекций google, ответ Tom можно упростить, используя ImmutableSet (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet. HTML)

Это действительно устраняет много беспорядка из предложенной инициализации

private static final Set<String> VALUES =  ImmutableSet.of("AB","BC","CD","AE");
+10
19 сент. '12 в 14:13
источник

Одно из возможных решений:

import java.util.Arrays;
import java.util.List;

public class ArrayContainsElement {
  public static final List<String> VALUES = Arrays.asList("AB", "BC", "CD", "AE");

  public static void main(String args[]) {

      if (VALUES.contains("AB")) {
          System.out.println("Contains");
      } else {
          System.out.println("Not contains");
      }
  }
}
+9
14 дек. '14 в 21:49
источник

Разработчики часто делают:

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);

Приведенный выше код работает, но нет необходимости конвертировать список для установки в первую очередь. Преобразование списка в набор требует дополнительного времени. Это может быть просто:

Arrays.asList(arr).contains(targetValue);

или

   for(String s: arr){
        if(s.equals(targetValue))
            return true;
    }

return false;

Первая из них более читаема, чем вторая.

+7
25 июн. '14 в 7:24
источник

В Java 8 используйте потоки.

List<String> myList =
Arrays.asList("a1", "a2", "b1", "c2", "c1");

myList
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
+6
28 апр. '15 в 6:40
источник

Использование простого цикла является наиболее эффективным способом сделать это.

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

Предоставлено Programcreek

+5
07 апр. '14 в 19:53
источник
  • Для массивов ограниченной длины используйте следующее (как указано camickr). Это медленно для повторных проверок, особенно для более длинных массивов (линейный поиск).

     Arrays.asList(...).contains(...)
    
  • Для быстрой работы, если вы неоднократно проверяете более широкий набор элементов

    • Массив - неправильная структура. Используйте TreeSet и добавьте к нему каждый элемент. Он сортирует элементы и имеет быстрый метод exist() (двоичный поиск).

    • Если элементы реализуют Comparable и вы хотите, чтобы TreeSet отсортировался соответственно:

      ElementClass.compareTo() метод должен быть совместим с ElementClass.equals(): см. Триады, не появляющиеся, чтобы сражаться? (Java Set отсутствует элемент)

      TreeSet myElements = new TreeSet();
      
      // Do this for each element (implementing *Comparable*)
      myElements.add(nextElement);
      
      // *Alternatively*, if an array is forceably provided from other code:
      myElements.addAll(Arrays.asList(myArray));
      
    • В противном случае используйте собственный Comparator:

      class MyComparator implements Comparator<ElementClass> {
           int compareTo(ElementClass element1; ElementClass element2) {
                // Your comparison of elements
                // Should be consistent with object equality
           }
      
           boolean equals(Object otherComparator) {
                // Your equality of comparators
           }
      }
      
      
      // construct TreeSet with the comparator
      TreeSet myElements = new TreeSet(new MyComparator());
      
      // Do this for each element (implementing *Comparable*)
      myElements.add(nextElement);
      
    • Выплата: проверьте наличие какого-либо элемента:

      // Fast binary search through sorted elements (performance ~ log(size)):
      boolean containsElement = myElements.exists(someElement);
      
+4
20 мая '13 в 7:34
источник

Используйте следующее (в этом коде метод contains() - ArrayUtils.in()):

ObjectUtils.java

public class ObjectUtils{

    /**
     * A null safe method to detect if two objects are equal.
     * @param object1
     * @param object2
     * @return true if either both objects are null, or equal, else returns false.
     */
    public static boolean equals(Object object1, Object object2){
        return object1==null ? object2==null : object1.equals(object2);
    }

}

ArrayUtils.java

public class ArrayUtils{

    /**
     * Find the index of of an object is in given array, starting from given inclusive index.
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @param start  The index from where the search must start.
     * @return Index of the given object in the array if it is there, else -1.
     */
    public static <T> int indexOf(final T[] ts, final T t, int start){
        for(int i = start; i < ts.length; ++i)
            if(ObjectUtils.equals(ts[i], t))
                return i;
        return -1;
    }

    /**
     * Find the index of of an object is in given array, starting from 0;
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @return  indexOf(ts, t, 0)
     */
    public static <T> int indexOf(final T[] ts, final T t){
        return indexOf(ts, t, 0);
    }

    /**
     * Detect if the given object is in the given array.
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @return  If indexOf(ts, t) is greater than -1.
     */
    public static <T> boolean in(final T[] ts, final T t){
        return indexOf(ts, t) > -1 ;
    }

}

Как видно из приведенного выше кода, есть и другие служебные методы ObjectUtils.equals() и ArrayUtils.indexOf(), которые также использовались в других местах.

+3
23 июл. '14 в 13:25
источник

Попробуйте следующее:

ArrayList<Integer> arrlist = new ArrayList<Integer>(8);

// use add() method to add elements in the list
arrlist.add(20);
arrlist.add(25);
arrlist.add(10);
arrlist.add(15);

boolean retval = arrlist.contains(10);
if (retval == true) {
    System.out.println("10 is contained in the list");
}
else {
    System.out.println("10 is not contained in the list");
}
+3
07 дек. '13 в 4:19
источник

Используйте Array.BinarySearch(array,obj) для нахождения данного объекта в массиве или нет.

Пример:

if (Array.BinarySearch(str, i) > -1)' → true --exists

ложь --not существует

+2
30 мая '13 в 6:59
источник

Если вы не хотите, чтобы это было чувствительно к регистру

Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);
+2
21 сент. '18 в 17:16
источник

Arrays.asList() ->, тогда вызов метода contains() всегда будет работать, но алгоритм поиска намного лучше, поскольку вам не нужно создавать упрощенную оболочку списка вокруг массива, что и делает Arrays.asList(),

public boolean findString(String[] strings, String desired){
   for (String str : strings){
       if (desired.equals(str)) {
           return true;
       }
   }
   return false; //if we get here… there is no desired String, return false.
}
+2
30 апр. '15 в 2:57
источник

Проверьте это

String[] VALUES = new String[] {"AB","BC","CD","AE"};
String s;

for(int i=0; i< VALUES.length ; i++)
{
    if ( VALUES[i].equals(s) )
    { 
        // do your stuff
    } 
    else{    
        //do your stuff
    }
}
+2
05 июн. '14 в 10:19
источник

Это может быть просто:

String[] VALUE = new String[] {"AB","BC","CD","AE"};
Arrays.asList(VALUE).contains(s);
+1
27 сент. '17 в 3:55
источник

Вот мой простой код, используя класс Arrays из пакета util. Это можно сделать многими другими способами, но, поставив вопрос, этот подход пришел мне на ум.

String a[] = {"abc","xyz","pqr"};
System.out.println(Arrays.asList(a).contains("abc")); //will return true
System.out.println(Arrays.asList(a).contains("abcd")); // will return false
0
03 окт. '18 в 13:17
источник

Создайте логическое значение, первоначально заданное как false. Запустите цикл, чтобы проверить каждое значение в массиве и сравнить с значением, которое вы проверяете. Если вы когда-либо получаете совпадение, установите boolean в true и остановите цикл. Тогда утвердим, что логическое значение истинно.

-2
17 мая '18 в 19:37
источник

Посмотрите другие вопросы по меткам или Задайте вопрос