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




удалить элемент массива java (20)

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

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

В массиве Unsorted:

  1. HashSet
  2. asList
  3. sort & Binary

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

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

Так или иначе, HashSet ftw

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

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

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


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 , LongStream или LongStream соответственно.

пример

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

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

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;

Первый - более читаемый, чем второй.


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

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

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

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

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

Поэтому, если массив создается в отсортированном порядке, бинарный поиск является самым быстрым, иначе asList () будет содержать путь. Если у вас много поисков, может быть целесообразно отсортировать массив, чтобы вы могли использовать двоичный поиск. Все зависит от вашего приложения.

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

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

Попробуй это:

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

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


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

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

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

enum Values {
    AB, BC, CD, AE
}

try {
    Values.valueOf(s);
    return true;
} catch (IllegalArgumentException exc) {
    return false;
}

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

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

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

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).


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

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

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


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

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

false - не существует


Я очень опаздываю, чтобы присоединиться к этой дискуссии, но поскольку мой подход к решению этой проблемы, когда я столкнулся с ней несколько лет назад, немного отличался от других ответов, уже размещенных здесь, я публикую это решение, которое я использовал в то время, здесь, если кто-нибудь найдет его полезным: (Метод 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() , которые также использовались в других местах.


Если у вас есть библиотека коллекций 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");

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

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

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


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

Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);

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

Вы можете использовать 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.
}

С помощью 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);
}

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

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




arrays