Pertanyaan Bagaimana saya bisa menguji apakah array mengandung nilai tertentu?


Saya punya String[] dengan nilai-nilai seperti:

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

Diberikan String s, apakah ada cara yang baik untuk menguji apakah VALUES mengandung s?


1850
2017-07-15 00:03


asal


Jawaban:


Arrays.asList(yourArray).contains(yourValue)

Peringatan: ini tidak berfungsi untuk larik primitif (lihat komentar).


Sejak

Anda sekarang dapat menggunakan Stream untuk memeriksa apakah array int, double atau long berisi nilai (masing-masing menggunakan a IntStream, DoubleStream atau LongStream)

Contoh

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

2423
2017-07-15 00:04



Hanya untuk menghapus kode untuk mulai dengan. Kami telah (diperbaiki):

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

Ini adalah statis yang dapat berubah yang FindBugs akan memberitahu Anda sangat nakal. Ini harus pribadi:

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

(Perhatikan, Anda benar-benar dapat menjatuhkan new String[]; sedikit.)

Jadi, array referensi buruk, dan khususnya di sini kita menginginkan satu set:

private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
     new String[] {"AB","BC","CD","AE"}
));

(Orang-orang paranoid, seperti saya, mungkin merasa lebih nyaman jika ini dibungkus Collections.unmodifiableSet - Itu bahkan bisa dipublikasikan.)

"Mengingat String, apakah ada cara yang bagus untuk menguji apakah VALUES mengandung s?"

VALUES.contains(s)

O (1).


309
2017-07-15 01:13



Kamu dapat memakai ArrayUtils.contains dari Apache Commons Lang

public static boolean contains(Object[] array, Object objectToFind)

Perhatikan bahwa metode ini kembali false jika array yang diteruskan adalah null.

Ada juga metode yang tersedia untuk array primitif dari semua jenis.

Contoh:

String[] fieldsToInclude = { "id", "name", "location" };

if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
    // Do some stuff.
}

171
2018-05-31 13:17



Saya terkejut tidak ada yang menyarankan untuk hanya menerapkannya dengan tangan:

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

Perbaikan:

Itu v != null kondisi konstan di dalam metode, selalu mengevaluasi ke nilai boolean yang sama selama pemanggilan metode. Jadi kalau input array besar, lebih efisien untuk mengevaluasi kondisi ini hanya sekali dan kita dapat menggunakan kondisi yang disederhanakan / lebih cepat di dalam for loop berdasarkan hasil. Yang diperbaiki contains() metode:

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

142
2017-09-28 07:45



Jika array tidak disortir, Anda harus mengulang semuanya dan membuat panggilan sama dengan masing-masing.

Jika array diurutkan, Anda dapat melakukan pencarian biner, ada satu di Array kelas.

Secara umum, jika Anda akan melakukan banyak pemeriksaan keanggotaan, Anda mungkin ingin menyimpan semuanya dalam Kumpulan, bukan dalam sebuah array.


65
2017-07-15 00:05



Empat Cara Berbeda untuk Memeriksa Jika Array Berisi Nilai

1) Menggunakan Daftar:

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

2) Menggunakan Set:

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

3) Menggunakan loop sederhana:

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

4) Menggunakan Arrays.binarySearch ():

Kode di bawah ini salah, tercantum di sini untuk kelengkapan. binarySearch () HANYA dapat digunakan pada array yang diurutkan. Anda akan menemukan hasilnya aneh di bawah ini. Ini adalah opsi terbaik ketika array diurutkan.

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

Contoh Cepat:

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

59
2018-05-07 19:14



Untuk apa nilainya saya menjalankan tes membandingkan 3 saran untuk kecepatan. Saya menghasilkan bilangan bulat acak, mengubahnya menjadi String dan menambahkannya ke array. Saya kemudian mencari angka / string tertinggi, yang akan menjadi skenario terburuk untuk asList (). Contains ().

Saat menggunakan ukuran 10K array, hasil di mana:

Urutkan & Cari: 15
Pencarian Biner: 0
asList.contains: 0

Ketika menggunakan hasil 100K array di mana:

Urutkan & Cari: 156
Pencarian Biner: 0
asList.contains: 32

Jadi, jika array dibuat dalam urutan terurut, pencarian biner adalah yang tercepat, jika tidak maka isList (). Berisi akan menjadi cara untuk pergi. Jika Anda memiliki banyak pencarian, mungkin ada baiknya untuk mengurutkan array sehingga Anda dapat menggunakan pencarian biner. Itu semua tergantung pada aplikasi Anda.

Saya akan berpikir itu adalah hasil yang diharapkan kebanyakan orang. Berikut ini kode uji:

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

46
2017-07-15 01:28



Alih-alih menggunakan sintaks inisialisasi deretan cepat untuk Anda hanya bisa menginisialisasi itu sebagai Daftar langsung dengan cara yang sama menggunakan metode Arrays.asList misalnya:

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

Maka Anda dapat melakukan (seperti di atas): STRINGS.contains("the string you want to find");


29
2018-01-20 13:58



Dengan Java 8 Anda dapat membuat aliran dan memeriksa apakah ada entri dalam aliran yang cocok "s":

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

Atau sebagai metode umum:

public static <T> boolean arrayContains(T[] array, T value) {
    return Arrays.stream(array).anyMatch(value::equals);
}

29
2018-03-13 14:53