Как определить, содержит ли массив определенное значение в Java?
У меня есть String[]
со значениями, например:
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
Учитывая String s
, есть ли хороший способ проверить, содержит ли VALUES
s
?
Ответы
Ответ 1
Arrays.asList(yourArray).contains(yourValue)
Предупреждение: это не работает для массивов примитивов (см. Комментарии).
Начиная с java-8 вы можете использовать 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);
Ответ 2
Просто чтобы очистить код для начала. Мы (исправили):
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 коллекций, как и следовало ожидать, по-прежнему не содержит неизменяемых типов коллекций, а синтаксис все еще слишком многословен, на мой вкус.)
Ответ 3
Вы можете использовать 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.
}
Ответ 4
Просто выполните это вручную:
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;
}
Ответ 5
Если массив не отсортирован, вам придется перебирать все и делать вызов равным для каждого.
Если массив отсортирован, вы можете выполнить двоичный поиск, там один в классе Arrays.
Вообще говоря, если вы собираетесь выполнять много проверок членства, вы можете захотеть сохранить все в наборе, а не в массиве.
Ответ 6
Четыре разных способа проверки, если массив содержит значение
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
Ответ 7
Для чего это я запустил тест, сравнивая 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));
}
}
Ответ 8
Вместо того, чтобы использовать синтаксис быстрой инициализации массива, вы можете просто инициализировать его в виде списка List сразу же, используя метод Arrays.asList, например:
public static final List<String> STRINGS = Arrays.asList("firstString", "secondString" ...., "lastString");
Тогда вы можете сделать (как выше):
STRINGS.contains("the string you want to find");
Ответ 9
С 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);
}
Ответ 10
Вы можете использовать класс Arrays для выполнения двоичного поиска значения. Если ваш массив не отсортирован, вам придется использовать функции сортировки в том же классе, чтобы отсортировать массив, а затем выполнить поиск по нему.
Ответ 11
ObStupidAnswer (но я думаю, что там где-то есть урок):
enum Values {
AB, BC, CD, AE
}
try {
Values.valueOf(s);
return true;
} catch (IllegalArgumentException exc) {
return false;
}
Ответ 12
На самом деле, если вы используете HashSet <String>, как предложил Том Хоутин, вам не нужно беспокоиться о сортировке, и ваша скорость такая же, как и при бинарном поиске в предварительно отсортированном массиве, возможно, даже быстрее.
Очевидно, все зависит от того, как настроен ваш код, но с того места, где я стою, порядок будет следующим:
На несортированном массиве:
- HashSet
- asList
- сортировать и двоичные
В отсортированном массиве:
- HashSet
- двоичный
- asList
Так или иначе, HashSet для победы.
Ответ 13
Если у вас есть библиотека коллекций 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");
Ответ 14
Одно из возможных решений:
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");
}
}
}
Ответ 15
Разработчики часто делают:
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;
Первая из них более читаема, чем вторая.
Ответ 16
Использование простого цикла является наиболее эффективным способом сделать это.
boolean useLoop(String[] arr, String targetValue) {
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
}
Предоставлено Programcreek
Ответ 17
В 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);
Ответ 18
-
Для массивов ограниченной длины используйте следующее (как указано 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);
Ответ 19
Попробуйте следующее:
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");
}
Ответ 20
Используйте следующее (в этом коде метод 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()
, которые также использовались в других местах.
Ответ 21
Используйте Array.BinarySearch(array,obj)
для нахождения данного объекта в массиве или нет.
Пример:
if (Array.BinarySearch(str, i) > -1)' → true --exists
ложь --not существует
Ответ 22
Проверьте это
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
}
}
Ответ 23
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.
}
Ответ 24
Если вы не хотите, чтобы это было чувствительно к регистру
Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);
Ответ 25
Это может быть просто:
String[] VALUE = new String[] {"AB","BC","CD","AE"};
Arrays.asList(VALUE).contains(s);
Ответ 26
Создайте логическое значение, первоначально заданное как false. Запустите цикл, чтобы проверить каждое значение в массиве и сравнить с значением, которое вы проверяете. Если вы когда-либо получаете совпадение, установите boolean в true и остановите цикл. Тогда утвердим, что логическое значение истинно.
Ответ 27
Вот мой простой код, используя класс 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
Ответ 28
Попробуйте использовать метод теста предикатов Java 8
Вот полный пример этого.
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Test {
public static final List<String> VALUES = Arrays.asList("AA", "AB", "BC", "CD", "AE");
public static void main(String args[]) {
Predicate<String> containsLetterA = VALUES -> VALUES.contains("AB");
for (String i : VALUES) {
System.out.println(containsLetterA.test(i));
}
}
}
http://mytechnologythought.blogspot.com/2019/10/java-8-predicate-test-method-example.html
https://github.com/VipulGulhane1/java8/blob/master/Test.java
Ответ 29
использование Spliterator
предотвращает ненужную генерацию List
boolean found = false; // class variable
String search = "AB";
Spliterator<String> spl = Arrays.spliterator( VALUES, 0, VALUES.length );
while( (! found) && spl.tryAdvance(o -> found = o.equals( search )) );
found == true
, если search
содержится в массиве
это работает для массивов примитивов
public static final int[] VALUES = new int[] {1, 2, 3, 4};
boolean found = false; // class variable
int search = 2;
Spliterator<Integer> spl = Arrays.spliterator( VALUES, 0, VALUES.length );
…
Ответ 30
Вы можете проверить это двумя способами
A) Путем преобразования массива в строку и проверки необходимой строки с помощью метода .contains
String a=Arrays.toString(VALUES);
System.out.println(a.contains("AB"));
System.out.println(a.contains("BC"));
System.out.println(a.contains("CD"));
System.out.println(a.contains("AE"));
B) это более эффективный метод
Scanner s=new Scanner(System.in);
String u=s.next();
boolean d=true;
for(int i=0;i<VAL.length;i++)
{
if(VAL[i].equals(u)==d)
System.out.println(VAL[i] +" "+u+VAL[i].equals(u));
}