Java, спрощена перевірка, чи масив int містить int


94

В основному мій товариш каже, що я міг би скоротити свій код, використовуючи інший спосіб перевірити, чи містить масив 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.
саркан

Ваш коментар означає, що зараз?
саркан

відповідь Hashsetна основі перевірки механізму повторного розгляду. Це найшвидший спосіб.
Amit Deshpande

Я не бачу сенсу скорочувати ваш вихідний код, оскільки ваш аргумент - це примітивний масив, а ваш код дуже чіткий і зрозумілий. ArrayListреалізація робить те саме.
Генцер

Я б не скорочував ваш код. (1) arraylist робить те саме, що і ви. (2) - важливішим є те, що скорочений код за допомогою Arrays.asList створює новий об'єкт, що може бути проблемою в межах певного продуктивного коду. Перший фрагмент коду - найкраще, що ви можете зробити.
Martin Podval

Відповіді:


38

Ось рішення Java 8

public static boolean contains(final int[] arr, final int key) {
    return Arrays.stream(arr).anyMatch(i -> i == key);
}

63

Ви можете просто використовувати ArrayUtils.containsз Apache Commons Lang library.

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

1
Поки ви використовуєте ArrayUtils, чи є якісь причини не використовувати ArrayUtils.contains
mjohnsonengr

2
Немає жодної причини :)
Реймеус

20
Варто зазначити, що ArrayUtils.contains()це частина Apache Commons Langбібліотеки. Незважаючи на те, що це чудова бібліотека, можливо, все-таки не є гарною ідеєю додавати зовнішню залежність просто для того, щоб перевірити, чи містить масив елемент: D
Krzysiek,

2
ArrayUtils - це минуле. Java 8+ та Guava мають досить дивовижні смаколики !!
TriCore

34

Це тому, що Arrays.asList(array)повернення List<int[]>. arrayаргумент трактується як одне значення, яке потрібно обернути (ви отримуєте список масивів ints), а не як 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
Чому автобокс не працює, це тому, що він оголошений остаточним?
субхаші

19

Гуава пропонує додаткові методи для примітивних типів. Серед них метод містить метод, який приймає ті самі аргументи, що і ваш.

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 of binarySearch (): "повернене значення буде> = 0 тоді і тільки тоді, коли ключ знайдений." тож Arrays.binarySearch (масив, ключ)> = 0 слід повернути!
icza

Додаток: Повернене значення binarySearch () дорівнює (- (точка вставки) - 1), якщо ключ не міститься, що, ймовірно, може бути значенням, відмінним від -1.
icza

Це не може бути, -1якщо воно має намір бути правдою. "Точка вставки визначається як точка, в яку ключ буде вставлений у список: індекс першого елемента, більший за ключ, або list.size (), якщо всі елементи у списку менше вказаного ключа. ". Треба сказати >= 0.
Брайан


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

Ви маєте рацію, спробуйте цей загальнодоступний статичний булев містить (фінальний масив int [], кінцевий ключ int) {return Arrays.stream (масив) .anyMatch (n-> n == ключ); }
Фархад Багіров

Потік 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(сортує).


Рядок handlig, як правило, дорогий, чому хтось повинен поводитися з ints як з рядком?
Денис Віталі

@DenysVitali Оскільки ОП вже має ефективне, ефективне рішення, і він шукає коротшого рішення. А ці коротші. Це питання не стосується продуктивності.
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;

              }


     }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.