Saya memiliki String[]
nilai-nilai seperti:
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
Mengingat String s
, apakah ada cara pengujian yang baik apakah VALUES
mengandung s
?
Saya memiliki String[]
nilai-nilai seperti:
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
Mengingat String s
, apakah ada cara pengujian yang baik apakah VALUES
mengandung s
?
Jawaban:
Arrays.asList(yourArray).contains(yourValue)
Peringatan: ini tidak berfungsi untuk array primitif (lihat komentar).
String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);
Untuk memeriksa apakah array int
, double
atau long
berisi penggunaan nilai IntStream
, DoubleStream
atau LongStream
masing - masing.
int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
ArrayList
, tapi tidak java.util.ArrayList
seperti yang Anda harapkan, kelas nyata yang dikembalikan: java.util.Arrays.ArrayList<E>
didefinisikan sebagai: public class java.util.Arrays {private static class ArrayList<E> ... {}}
.
Array referensi buruk. Untuk kasus ini kita mengejar set. Sejak Java SE 9 kita miliki Set.of
.
private static final Set<String> VALUES = Set.of(
"AB","BC","CD","AE"
);
"Diberikan String s, apakah ada cara yang baik untuk menguji apakah VALUES berisi s?"
VALUES.contains(s)
O (1).
The jenis yang tepat , berubah , O (1) dan ringkas . Cantik.*
Hanya untuk menghapus kode untuk memulai. Kami telah (dikoreksi):
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
Ini adalah statik yang bisa berubah yang FindBugs akan bilang sangat nakal. Jangan modifikasi statika dan jangan izinkan kode lain melakukannya juga. Paling tidak absolut, bidang harus pribadi:
private static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
(Catatan, Anda dapat benar-benar menjatuhkan new String[];
bit.)
Array referensi masih buruk dan kami ingin satu set:
private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
new String[] {"AB","BC","CD","AE"}
));
(Orang paranoid, seperti saya, mungkin merasa lebih nyaman jika ini dibungkus Collections.unmodifiableSet
- itu bahkan dapat dipublikasikan).
(* Untuk sedikit lebih pada merek, API koleksi diperkirakan masih kehilangan tipe koleksi yang tidak berubah dan sintaksisnya masih terlalu bertele-tele, untuk selera saya.)
Arrays.asList
)?
TreeSet
akan menjadi O(log n)
. HashSet
s diskalakan sedemikian rupa sehingga jumlah rata-rata elemen dalam ember kira-kira konstan. Setidaknya untuk array hingga 2 ^ 30. Mungkin ada pengaruh dari, katakanlah, cache perangkat keras yang diabaikan oleh analisis big-O. Juga mengasumsikan fungsi hash bekerja secara efektif.
Anda dapat menggunakan 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 semua jenis array primitif.
String[] fieldsToInclude = { "id", "name", "location" };
if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
// Do some stuff.
}
Cukup dengan 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:
The v != null
kondisi konstan dalam metode. Itu selalu mengevaluasi ke nilai Boolean yang sama selama pemanggilan metode. Jadi jika inputnya array
besar, lebih efisien untuk mengevaluasi kondisi ini hanya sekali, dan kita bisa menggunakan kondisi yang disederhanakan / lebih cepat di dalam for
loop berdasarkan hasil. contains()
Metode yang ditingkatkan :
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;
}
Collection.contains(Object)
Arrays
dan ArrayList
ternyata ini belum tentu lebih cepat daripada menggunakan versi Arrays.asList(...).contains(...)
. Overhead membuat ArrayList
sangat kecil, dan ArrayList.contains()
menggunakan loop cerdas (sebenarnya menggunakan dua loop berbeda) daripada yang ditunjukkan di atas (JDK 7).
Empat Cara Berbeda untuk Memeriksa Jika Array Mengandung 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;
}
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
Jika array tidak diurutkan, Anda harus mengulang semuanya dan membuat panggilan untuk menyamakan masing-masing.
Jika array diurutkan, Anda dapat melakukan pencarian biner, ada satu di kelas Array .
Secara umum, jika Anda akan melakukan banyak pemeriksaan keanggotaan, Anda mungkin ingin menyimpan semuanya dalam Set, bukan dalam array.
Untuk apa nilainya saya menjalankan tes membandingkan 3 saran untuk kecepatan. Saya menghasilkan bilangan bulat acak, mengubahnya menjadi String dan menambahkannya ke sebuah array. Saya kemudian mencari angka / string tertinggi, yang akan menjadi skenario terburuk untukasList().contains()
.
Saat menggunakan ukuran array 10K, hasilnya adalah:
Sortir & Cari: 15 Pencarian Biner: 0 asList.contains: 0
Saat menggunakan array 100K, hasilnya adalah:
Sortir & Cari: 156 Pencarian Biner: 0 asList.contains: 32
Jadi jika array dibuat dalam urutan, pencarian biner adalah yang tercepat, jika tidak maka asList().contains
akan menjadi cara untuk pergi. Jika Anda memiliki banyak pencarian, mungkin ada baiknya menyortir array sehingga Anda dapat menggunakan pencarian biner. Itu semua tergantung pada aplikasi Anda.
Saya pikir itu adalah hasil yang diharapkan kebanyakan orang. Ini adalah kode tes:
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));
}
}
Daripada menggunakan sintaks inisialisasi array cepat juga, Anda bisa langsung menginisialisasi sebagai Daftar 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");
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);
}
anyMatch
JavaDoc menyatakan itu "...May not evaluate the predicate on all elements if not necessary for determining the result."
, jadi mungkin tidak perlu melanjutkan pemrosesan setelah menemukan kecocokan.
Anda bisa menggunakan kelas Array untuk melakukan pencarian biner untuk nilai. Jika array Anda tidak diurutkan, Anda harus menggunakan fungsi sortir di kelas yang sama untuk mengurutkan array, lalu cari.
ObStupidAnswer (tapi saya pikir ada pelajaran di sini di suatu tempat):
enum Values {
AB, BC, CD, AE
}
try {
Values.valueOf(s);
return true;
} catch (IllegalArgumentException exc) {
return false;
}
Sebenarnya, jika Anda menggunakan HashSet <String> seperti yang diusulkan oleh Tom Hawtin, Anda tidak perlu khawatir tentang penyortiran, dan kecepatan Anda sama dengan pencarian biner pada array yang dipilih, mungkin bahkan lebih cepat.
Itu semua tergantung pada bagaimana kode Anda diatur, tentu saja, tetapi dari tempat saya berdiri, urutannya adalah:
Pada array yang tidak disortir :
Pada array yang diurutkan:
Jadi, HashSet untuk menang.
Jika Anda memiliki perpustakaan koleksi google, jawaban Tom dapat disederhanakan banyak dengan menggunakan ImmutableSet (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html)
Ini benar-benar menghilangkan banyak kekacauan dari inisialisasi yang diusulkan
private static final Set<String> VALUES = ImmutableSet.of("AB","BC","CD","AE");
Satu solusi yang mungkin:
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");
}
}
}
Pengembang sering melakukan:
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
Kode di atas berfungsi, tetapi tidak perlu mengonversi daftar untuk ditetapkan terlebih dahulu. Mengonversi daftar ke perangkat memerlukan waktu ekstra. Ini bisa sesederhana:
Arrays.asList(arr).contains(targetValue);
atau
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
Yang pertama lebih mudah dibaca daripada yang kedua.
Menggunakan loop sederhana adalah cara paling efisien untuk melakukan ini.
boolean useLoop(String[] arr, String targetValue) {
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
}
Atas perkenan Programcreek
Di Java 8 gunakan 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);
Untuk array dengan panjang terbatas gunakan yang berikut (seperti yang diberikan oleh camickr ). Ini lambat untuk pemeriksaan berulang, terutama untuk array yang lebih panjang (pencarian linear).
Arrays.asList(...).contains(...)
Untuk kinerja cepat jika Anda berulang kali mengecek elemen yang lebih besar
Array adalah struktur yang salah. Gunakan a TreeSet
dan tambahkan setiap elemen ke dalamnya. Ini memilah elemen dan memiliki exist()
metode cepat (pencarian biner).
Jika elemen menerapkan Comparable
& Anda ingin TreeSet
diurutkan sesuai:
ElementClass.compareTo()
Metode harus kompatibel dengan ElementClass.equals()
: lihat Triad tidak muncul untuk bertarung? (Java Atur item yang hilang)
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));
Jika tidak, gunakan milik Anda sendiri 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);
Imbalannya: periksa keberadaan beberapa elemen:
// Fast binary search through sorted elements (performance ~ log(size)):
boolean containsElement = myElements.exists(someElement);
TreeSet
? HashSet
lebih cepat (O (1)) dan tidak perlu dipesan.
Coba ini:
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");
}
Gunakan yang berikut ini ( contains()
metode ada ArrayUtils.in()
dalam kode ini):
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 ;
}
}
Seperti yang Anda lihat dalam kode di atas, bahwa ada metode utilitas lain ObjectUtils.equals()
dan ArrayUtils.indexOf()
, yang digunakan di tempat lain juga.
Periksa ini
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
}
}
else
untuk setiap item yang tidak cocok (jadi jika Anda mencari "AB" dalam array itu, ia akan pergi ke sana 3 kali, karena 3 dari nilai tidak "AB ").
Arrays.asList () -> lalu memanggil metode contain () akan selalu berfungsi, tetapi algoritma pencarian jauh lebih baik karena Anda tidak perlu membuat pembungkus daftar ringan di sekitar array, yang dilakukan oleh 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.
}
Arrays.asList
bukan O (n). Itu hanya pembungkus ringan. Lihatlah implementasinya.
Jika Anda tidak ingin menjadi case sensitif
Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);
Gunakan Array.BinarySearch(array,obj)
untuk menemukan objek yang diberikan dalam array atau tidak.
Contoh:
if (Array.BinarySearch(str, i) > -1)` → true --exists
false - tidak ada
Array.BinarySearch
dan Array.FindIndex
. Metode NET dan tidak ada di Jawa.
The array must be sorted prior to making this call. If it is not sorted, the results are undefined.
Coba gunakan metode tes predikat Java 8
Ini adalah contoh lengkapnya.
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
penggunaan a Spliterator
mencegah generasi a yang tidak perlu 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
jika search
terkandung dalam array
ini tidak bekerja untuk array primitif
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 );
…
Karena saya berurusan dengan Java tingkat rendah menggunakan byte dan byte tipe primitif, yang terbaik sejauh ini saya dapatkan dari byte-java https://github.com/patrickfav/bytes-java tampaknya merupakan karya yang bagus
Anda dapat memeriksanya dengan dua metode
A) Dengan mengubah array menjadi string dan kemudian memeriksa string yang diperlukan dengan metode .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) ini adalah metode yang lebih efisien
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));
}