Java, упрощенная проверка, содержит ли массив int int

95

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

Текущий:

public boolean contains(final int[] array, final int key) {
    for (final int i : array) {
        if (i == key) {
            return true;
        }
    }
    return false;
}

Также пробовали это, хотя по какой-то причине он всегда возвращает false.

public boolean contains(final int[] array, final int key) {
    return Arrays.asList(array).contains(key);
}

Может ли кто-нибудь мне помочь?

Спасибо.

Калеб
источник
8
Ваш вызов Arrays.asList (...) принимает vararg, то есть он переносит произвольное количество аргументов, которые вы можете передать в него в списке. В вашем случае вы получаете список массивов с одним элементом, и этот список, очевидно, не содержит int.
sarcan
Что теперь означает ваш комментарий?
sarcan
Hashsetответ механизма повторной проверки на основе проверки . Это самый быстрый способ.
Амит Дешпанде,
Я не вижу смысла делать ваш исходный код короче, поскольку ваш аргумент является примитивным массивом, а ваш код очень ясен и прямолинеен. ArrayListреализация делает то же самое.
Genzer
Я бы не стал делать ваш код короче. (1) Arraylist делает то же самое, что и вы. (2) - более важный момент заключается в том, что сокращенный код с использованием Arrays.asList создает новый объект, что может быть проблемой в некотором критичном для производительности коде. Первый фрагмент кода - лучшее, что вы можете сделать.
Мартин Подвал

Ответы:

39

Вот решение Java 8

public static boolean contains(final int[] arr, final int key) {
    return Arrays.stream(arr).anyMatch(i -> i == key);
}
TriCore
источник
64

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

public boolean contains(final int[] array, final int key) {     
    return ArrayUtils.contains(array, key);
}
Реймеус
источник
1
Пока вы используете ArrayUtils, есть ли причина не использовать ArrayUtils.contains
mjohnsonengr
2
Никакой причины :)
Reimeus
20
Стоит отметить, что ArrayUtils.contains()это часть Apache Commons Langбиблиотеки. Несмотря на то, что это отличная библиотека, вероятно, все еще не рекомендуется добавлять внешнюю зависимость, чтобы проверить, содержит ли массив элемент: D
Krzysiek
2
ArrayUtils ушел в прошлое. У Java 8+ и Guava есть замечательные штуки !!
TriCore
34

Это потому что Arrays.asList(array)возвращение List<int[]>. arrayАргумент рассматривается как одно значение, которое вы хотите обернуть (вы получаете список массивов целых чисел), а не как vararg.

Обратите внимание , что это делает работу с типами объектов (не примитивы):

public boolean contains(final String[] array, final String key) {
    return Arrays.asList(array).contains(key);
}

или даже:

public <T>  boolean contains(final T[] array, final T key) {
    return Arrays.asList(array).contains(key);
}

Но нельзя, List<int>и автобокс здесь не работает.

Томаш Нуркевич
источник
1
Почему автобокс не работает, потому что он объявлен окончательным?
subhashis
19

Guava предлагает дополнительные методы для примитивных типов. Среди них есть метод, который принимает те же аргументы, что и ваш.

public boolean contains(final int[] array, final int key) {
    return Ints.contains(array, key);
}

Вы также можете статически импортировать версию гуавы.

См. Объяснение примитивов гуавы

Эверт
источник
18

Другой способ:

public boolean contains(final int[] array, final int key) {  
     Arrays.sort(array);  
     return Arrays.binarySearch(array, key) >= 0;  
}  

Это изменяет переданный массив. У вас будет возможность скопировать массив и работать с исходным массивом, т.е. int[] sorted = array.clone();
это всего лишь пример короткого кода. Время выполнения O(NlogN)пока ваш путьO(N)

Кратил
источник
30
Думаю, я был бы удивлен, если бы какой- containsнибудь метод изменил мой массив.
Zong
@ZongLi: Это просто пример для OP.Updated OP , если мы придирка
Кратили
5
Из javadoc из binarySearch (): «возвращаемое значение будет> = 0, если и только если ключ найден». поэтому должен быть возвращен Arrays.binarySearch (array, key)> = 0!
icza
Дополнение: возвращаемое значение binarySearch () равно (- (точка вставки) - 1), если ключ не содержится, что, вероятно, может быть значением, отличным от -1.
icza
Этого не может быть, -1если это действительно так. "Точка вставки определяется как точка, в которой ключ будет вставлен в список: индекс первого элемента больше, чем ключ, или list.size (), если все элементы в списке меньше указанного ключа. ". Надо сказать >= 0.
Брайан
17

Я знаю, что уже очень поздно, но попробуй Integer[]вместо этого int[].

Вилли Вонка
источник
Это решение.
atheesh27
1

1. одноразовое использование

List<T> list=Arrays.asList(...)
list.contains(...)

2. используйте HashSet для оценки производительности, если вы используете более одного раза.

Set <T>set =new HashSet<T>(Arrays.asList(...));
set.contains(...)
Джаски
источник
1

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

public static void arrayContains(){
    int myArray[]={2,2,5,4,8};

    int length=myArray.length;

    int toFind = 5;
    boolean found = false;

    for(int i = 0; i < length; i++) {
        if(myArray[i]==toFind) {
            found=true;
        }
    }

    System.out.println(myArray.length);
    System.out.println(found); 
}
Элаварасан С
источник
1

Вы можете преобразовать свой примитивный массив int в массив целых чисел, используя приведенный ниже код Java 8,

List<Integer> arrayElementsList = Arrays.stream(yourArray).boxed().collect(Collectors.toList());

А затем используйте contains()метод, чтобы проверить, содержит ли список определенный элемент,

boolean containsElement = arrayElementsList.contains(key);
Хетал Рах
источник
0

это работало в java 8

public static boolean contains(final int[] array, final int key)
{
return Arrays.stream(array).anyMatch(n->n==key);
}
Фархад Багиров
источник
Он должен немедленно вернуться при первом совпадении, вместо этого он все равно будет сканировать все элементы в массиве, даже если он нашел совпадение. (Рассмотрим набор из триллионов предметов)
TriCore
Вы правы, попробуйте этот публичный статический логический элемент contains (final int [] array, final int key) {return Arrays.stream (array) .anyMatch (n-> n == key); }
Фархад Багиров
Поток Java 8 anyMatch является операцией короткого замыкания и не будет сканировать все элементы в массиве.
LordParsley
@LordParsley Целью приведенного выше кода является проверка элемента в массиве, а не сканирование всего элемента массива.
Фархад Багиров
Извините, я вижу, что ответ был отредактирован. Я просто повторил, что это было правильно, так как не нужно будет сканировать все, если он найдет одну часть пути.
LordParsley
0

Вы можете использовать java.util.Arraysкласс для преобразования массива T[?]в List<T>объект с помощью таких методов, как contains:

Arrays.asList(int[] array).contains(int key);
Мурад Эль Аомари
источник
-1

В зависимости от того, насколько большим будет ваш массив int, вы получите гораздо лучшую производительность, если будете использовать коллекции, .containsа не выполнять итерацию по массиву по одному элементу за раз:

import static org.junit.Assert.assertTrue;
import java.util.HashSet;

import org.junit.Before;
import org.junit.Test;

public class IntLookupTest {

int numberOfInts = 500000;
int toFind = 200000;
int[] array;

HashSet<Integer> intSet;

@Before
public void initializeArrayAndSet() {
    array = new int[numberOfInts];
    intSet = new HashSet<Integer>();
    for(int i = 0; i < numberOfInts; i++) {
        array[i] = i;
        intSet.add(i);
    }
}

@Test
public void lookupUsingCollections() {
    assertTrue(intSet.contains(toFind));
}

@Test
public void iterateArray() {
    assertTrue(contains(array, toFind));

}

public boolean contains(final int[] array, final int key) {
    for (final int i : array) {
        if (i == key) {
            return true;
        }
    }
    return false;
}
}
Кавех Гахремани
источник
-1

Решение # 1

Поскольку исходный вопрос требует только упрощенного решения (а не более быстрого), вот однострочное решение:

public boolean contains(int[] array, int key) {
    return Arrays.toString(array).matches(".*[\\[ ]" + key + "[\\],].*");
}

Объяснение: В документации Javadoc Arrays.toString()указано, что результат заключен в квадратные скобки, а соседние элементы разделены символами «,» (запятая, за которой следует пробел). Так что мы можем на это рассчитывать. Сначала мы конвертируем arrayв строку, а затем проверяем, keyсодержится ли в этой строке. Конечно, мы не можем принимать «субчисла» (например, «1234» содержит «23»), поэтому мы должны искать шаблоны, в которых перед keyсимволом стоит открывающая скобка или пробел, а за ним следует закрывающая скобка или запятая.

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

Решение # 2

Это решение уже опубликовано, но содержит ошибки, поэтому я публикую правильное решение:

public boolean contains(int[] array, int key) {
    Arrays.sort(array);
    return Arrays.binarySearch(array, key) >= 0;
}

Также у этого решения есть побочный эффект: оно изменяет array(сортирует).

icza
источник
Обработка строк обычно обходится дорого, почему кто-то должен рассматривать целые числа как строку?
Денис Виталий
@DenysVitali Потому что у op уже есть работающее эффективное решение, и он ищет более короткое решение. И они короче. Это вопрос не о производительности.
icza
Тогда я должен был неправильно понять вопрос, извините, что спросил
Денис Витали
-5

Попробуйте Integer.parseInt()сделать это .....

public boolean chkInt(final int[] array){
    int key = false;

    for (Integer i : array){


          try{

                   Integer.parseInt(i);
                   key = true;
                   return key;

             }catch(NumberFormatException ex){

                   key = false;

                   return key;

              }


     }
}
Кумар Вивек Митра
источник