Bir dizinin Java'da belirli bir değer içerip içermediğini nasıl belirlerim?


2276

Ben böyle String[]değerleri ile bir var :

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

Verilen String s, içerip VALUESiçermediğini test etmenin iyi bir yolu var mı s?


5
Etrafında uzun bir yol var, ancak for döngüsü kullanabilirsiniz: "(String s: VALUES) için (s.equals (" MYVALUE ")) true değerini döndürürse
Zack

70
@camickr. Sorunuza, bu soruyu ve cevabınızı iptal ettim -için- çünkü 30 dakika ve 20 satır kodları çirkinler için çirkin bir şekilde yazdı, -now-. Üç yıl önce okumadım. (BTW, teşekkürler :))
Takip

3
@ camickr - Ben bununla neredeyse aynı bir durum var: stackoverflow.com/a/223929/12943 Sadece oy almaya devam ediyor ama sadece güneş belgelerinden bir kopya / yapıştır oldu. Sanırım puan ne kadar yardım sağladığınıza ve ne kadar çaba harcadığınıza ve çoğunlukla ne kadar hızlı yayınladığınıza bağlı! Belki de John Skeet'in sırrını tökezledik! Güzel cevap, +1 sizin için.
Bill K

1
Apache Commons kullanıyorsanız, org.apache.commons.lang.ArrayUtils.contains () bunu sizin için yapar.
Bay Boy

34
@camickr çünkü insanlar, benim gibi, bir soru google, SO sonucunu tıklayın, cevabınızı görün, test edin, işe yarıyor, cevabı onaylayın ve sonra ayrılın.
Aequitas

Yanıtlar:


2923
Arrays.asList(yourArray).contains(yourValue)

Uyarı: Bu, ilkel diziler için geçerli değildir (yorumlara bakın).


Dan beri artık Akışları kullanabilirsiniz.

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

Bir dizi kontrol etmek için int, doubleya da longbir değer kullanımını içerir IntStream, DoubleStreamya da LongStreamsırasıyla.

Misal

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

87
Ben bir dizi üzerinden yineleme ve ilkel için bir equals () işlevi veya == kullanarak Arrays sınıfında arama işlevlerine karşı bu performans performansını merak ediyorum.
Thomas Owens

186
AsList () öğesi, kalbinde bir dizi bulunan bir ArrayList döndürdüğü için fazla kaybetmezsiniz. Yapıcı sadece bir referans değiştirecek, bu yüzden orada yapılacak çok iş yok. Ve tekrarlar ve eşittir () kullanır içerir () / indexOf (). İlkel için, kendiniz kodlamaktan daha iyi olmalısınız. Dizeler veya diğer sınıflar için fark fark edilmeyecektir.
Joey

18
Garip, NetBeans 'int [] tatilleri için' Arrays.asList (holidays) 'ifadesinin' list <int> 'yerine' list <int []> 'döndürdüğünü iddia ediyor. Yalnızca tek bir öğe içerir. Yani İçerir, sadece bir unsuru olduğu için çalışmaz; int dizisi.
Nyerguds

62
Nyerguds: gerçekten, bu ilkel için işe yaramaz. Java'da ilkel tipler genel olamaz. asList <T> Liste <T> olarak asList (T ...) olarak bildirilir. İçine bir int [] ilettiğinizde, derleyici T = int [] 'i bozar, çünkü T = int çıkarım yapamaz, çünkü ilkeller genel olamaz.
CromTheDestroyer

28
@Joey sadece bir yan not, bu bir var ArrayList, ama java.util.ArrayListbeklediğiniz gibi, gerçek sınıf döndürülen: java.util.Arrays.ArrayList<E>olarak tanımlanır: public class java.util.Arrays {private static class ArrayList<E> ... {}}.
TWiStErRob

362

Java SE 9 için kısa güncelleme

Referans dizileri bozuk. Bu durumda bir set peşindeyiz. Java SE 9'dan beri var Set.of.

private static final Set<String> VALUES = Set.of(
    "AB","BC","CD","AE"
);

"String'ler verildiğinde, VALUES öğesinin s içerip içermediğini test etmenin iyi bir yolu var mı?"

VALUES.contains(s)

O (1).

Sağ türü , değişmez , O (1) ve kısa . Güzel.*

Orijinal cevap ayrıntıları

Sadece başlamak için kodu temizlemek için. Biz (düzelttik):

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

Bu, FindBugs'in size çok yaramaz olduğunu söyleyeceği değiştirilebilir bir statiktir. Statiği değiştirmeyin ve diğer kodların da buna izin vermeyin. Mutlak minimumda, alan özel olmalıdır:

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

(Not, aslında new String[];biraz düşebilir .)

Referans dizileri hala kötü ve bir dizi istiyoruz:

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

(Kendim gibi paranoyak insanlar, eğer sarılırsa daha rahat hissedebilir Collections.unmodifiableSet- o zaman halka açık bile olabilir.)

(* Markada biraz daha fazla olmak için, koleksiyon API'sı tahmin edilemeyecek şekilde hala değişmez koleksiyon türlerini kaçırıyor ve sözdizimi, zevklerim için hala çok ayrıntılı.)


184
İlk olarak koleksiyonu oluşturmak için O (N) hariç :)
Drew Noakes

61
Statik ise, muhtemelen birkaç kez kullanılacaktır. Bu nedenle, seti başlatmak için harcanan zaman, birçok doğrusal aramanın maliyetine kıyasla oldukça küçük olma şansına sahiptir.
Xr.

1
Daha sonra koleksiyonun oluşturulmasına kod yükleme süresi hakim olacaktır (teknik olarak O (n) ancak pratik olarak sabittir).
Tom Hawtin - taktik

2
@ TomHawtin-tackline Neden "özellikle burada bir set istiyoruz" diyorsunuz? Bu durumda bir Setin (HashSet) avantajı nedir? Neden "başvuru dizisi" kötü ("başvuru dizisi" ile çağrının oluşturduğu gibi bir dizi tarafından desteklenen bir ArrayList mi demek istersiniz Arrays.asList)?
Basil Bourque

6
@nmr A TreeSetolur O(log n). HashSetbir kovadaki ortalama eleman sayısı kabaca sabit olacak şekilde ölçeklendirilir. En azından 2 ^ 30'a kadar diziler için. Diyelim ki big-O analizinin göz ardı ettiği donanım önbellekleri olabilir. Ayrıca hash işlevinin etkili bir şekilde çalıştığını varsayar.
Tom Hawtin - taktik

206

Sen kullanabilirsiniz ArrayUtils.containsgelen Apache Commons Lang

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

falseGeçirilen dizi ise bu yöntemin döndüğünü unutmayın null.

Her çeşit ilkel diziler için de yöntemler vardır.

Misal:

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

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

4
@ max4ever katılıyorum, ama bu hala "kendi haddeleme" sonra daha iyi ve ham java yolu okumak daha kolay.
Jason


38
@ max4ever Bazen bu kitaplığı zaten dahil etmişsinizdir (başka nedenlerle) ve tamamen geçerli bir cevaptır. Bunu arıyordum ve zaten Apache Commons Lang'a bağlıyım. Bu cevap için teşekkürler.
GuiSim

1
Ya da sadece yöntemi (ve varsa bağımlılıkları) kopyalayabilirsiniz.
Buffalo

10
@ max4ever Çoğu android uygulaması Proguard tarafından en aza indirgenir ve yalnızca gereksinim duyduğunuz sınıfları ve işlevleri uygulamanıza yerleştirir. Bu, kendinizinkini yuvarlamaya veya apache öğesinin kaynağını kopyalamaya eşit yapar. Ve kim bu minimalizasyon kullanmaz 700kb veya 78kb hakkında şikayet gerekmez :)
Kenyakorn Ketsombut

158

Sadece elle uygulayın:

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

Gelişme:

v != nullDurum yöntemi içinde sabittir. Yöntem çağrısı sırasında her zaman aynı Boole değerini değerlendirir. Dolayısıyla girdi arraybüyükse, bu durumu yalnızca bir kez değerlendirmek daha verimlidir forve sonuca bağlı olarak döngü içinde basitleştirilmiş / daha hızlı bir koşul kullanabiliriz . Geliştirilmiş contains()yöntem:

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

9
@Phoexo Bu çözüm açıkça daha hızlıdır çünkü kabul edilen cevap diziyi bir listeye sarar ve benim çözümüm temel olarak yalnızca () ne yaparsa yapsın, bu listedeki include () yöntemini çağırır.
icza

10
@AlastorMoody e == v, çok hızlı bir referans eşitlik kontrolü yapar. Aynı nesne (başvuru ile aynı) dizide ise, daha hızlı bulunur. Aynı örnek değilse, yine de equals () yöntemi tarafından talep edilenle aynı olabilir, referanslar aynı değilse bu kontrol edilir.
icza

20
Bu işlev neden Java'nın bir parçası değil? İnsanların Java'nın şişirildiğini söylemelerine şaşmamalı ... Bunun için ihtiyacınız olan tek şey bir döngü olduğunda bir grup kitaplık kullanan tüm cevaplara bakın. Çocuklar bugünlerde!
phreakhead

4
@phreakhead Java'nın bir parçası, bkz.Collection.contains(Object)
Steve Kuo

11
@icza Kaynağına bakarsanız Arraysve ArrayListbunun sürümün kullanılmasından daha hızlı olmadığı ortaya çıkıyor Arrays.asList(...).contains(...). A oluşturma yükü ArrayListson derece küçüktür ve ArrayList.contains()yukarıda gösterilenlerden (JDK 7) daha akıllı bir döngü kullanır (aslında iki farklı döngü kullanır).
Axel

72

Bir Dizinin Değer İçerip İçermediğini Kontrol Etmenin Dört Farklı Yolu

1) Liste Kullanarak:

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

2) Set kullanarak:

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

3) Basit bir döngü kullanarak:

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

4) Arrays.binarySearch () kullanılması:

Aşağıdaki kod yanlış, tamlık için burada listelenmiştir. binarySearch () SADECE sıralı dizilerde kullanılabilir. Sonucun garip olduğunu göreceksiniz. Dizi sıralandığında bu en iyi seçenektir.

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

Hızlı Örnek:

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

5
ikili arama örneğiniz> 0 döndürmelidir;
Sherwood

6
Neden? 0, dizinin başında yer alacağını gösterdiğinden, bir> -1 döndürmesi gerektiğini düşünüyorum.
16:15

1
İlk varyantı (a >= 0)doğruydu, sadece dokümanları kontrol edin , "Bunun dönüş değerinin yalnızca anahtar bulunursa> = 0 olacağını garanti ettiğini" söylediler.
Yoory N.30

Neden string için değil int için çalışıyor? statik boole vardır (int [] ints, int k) {return Arrays.asList (ints) .contains (k); }
Willians Martins

71

Dizi sıralanmamışsa, her şeyi yinelemeniz ve her birine eşittir çağrısı yapmanız gerekir.

Dizi sıralanırsa, ikili bir arama yapabilirsiniz, Diziler sınıfında bir tane var.

Genel olarak konuşursak, çok sayıda üyelik kontrolü yapacaksanız, her şeyi bir dizide değil, bir Sette saklamak isteyebilirsiniz.


1
Ayrıca, cevabımda söylediğim gibi, Arrays sınıfını kullanırsanız, diziyi sıralayabilir ve yeni sıralanan dizide ikili arama yapabilirsiniz.
Thomas Owens

1
@Thomas: Katılıyorum. Veya her şeyi bir TreeSet'e ekleyebilirsiniz; aynı karmaşıklık. Değişmezse Diziler'i kullanırdım (dizeler olmasa da referanslar bitişik olarak bulunduğundan belki biraz bellek yerinden tasarruf edin). Bu, zaman içinde değişecekse seti kullanırım.
Uri

49

Değeri için hız için 3 önerileri karşılaştıran bir test yaptım. Rastgele tamsayılar oluşturdum, bunları bir String'e dönüştürdüm ve bir diziye ekledim. Daha sonra için en kötü durum senaryosu olacağını mümkün olan en yüksek sayı / dize aradı asList().contains().

10K dizi boyutu kullanıldığında sonuçlar şunlardı:

Sırala ve Ara: 15
İkili Arama: 0
asList.contains: 0

100K dizisi kullanıldığında sonuçlar şunlardı:

Sırala ve Ara: 156
İkili Arama: 0
asList. içerir: 32

Yani dizi sıralı olarak oluşturulursa ikili arama en hızlıdır, aksi takdirde asList().containsgitmek için bir yol olacaktır. Çok sayıda aramanız varsa, ikili aramayı kullanabilmeniz için diziyi sıralamak faydalı olabilir. Her şey uygulamanıza bağlıdır.

Bunların çoğu insanın bekleyeceği sonuçlar olduğunu düşünürüm. İşte test kodu:

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

6
Bu kodu anlamıyorum. 'Dizeleri' dizisini sıralarsınız ve her iki binarySearch çağrısında da aynı (sıralanmış) diziyi kullanırsınız. Bu HotSpot çalışma zamanı optimizasyonu dışında bir şeyi nasıl gösterebilir? Aynı şey asList.con çağrısı için de geçerlidir. Sıralanan diziden bir liste oluşturursunuz ve daha sonra en yüksek değere sahip listeyi içerir. Tabii ki zaman alacak. Bu testin anlamı nedir? Yanlış yazılmış bir mikrobenchmark olduğundan bahsetmiyorum bile
Erik

Ayrıca, ikili arama yalnızca sıralı bir kümeye uygulanabildiğinden, ikili aramayı kullanmanın tek yolu sıralama ve aramadır.
Erik

Sıralama zaten başka birçok nedenden dolayı yapılmış olabilir, örneğin init üzerinde sıralanabilir ve asla değiştirilemez. Arama süresini tek başına test etmenin bir faydası vardır. Ancak bunun düştüğü yerde mikrobençlemenin yıldız örneğinden daha az olması söz konusudur. Mikrobenç işaretlerinin Java'da doğru bir şekilde elde edilmesi çok zordur ve örneğin, gerçek test kodunu bir zamanlayıcı ile ONCE'den daha fazla çalıştırmak yerine, gerçek testi çalıştırmadan önce etkin nokta optimizasyonu elde etmek için test kodunun yürütülmesini içermelidir. Örnek tuzaklar
Thor84no

7
Bu test, aynı JVM örneğinde 3 testin tümünü çalıştırdığı için kusurludur . Daha sonraki testler, önbelleği, JIT'i vb. Isıtan öncekilerden yararlanabilir
Steve Kuo

4
Bu test aslında tamamen ilgisiz. Sıralama ve Arama doğrusallık (n * log (n)) karmaşıklığı, ikili arama logaritmik ve ArrayUtils.contains açıkça doğrusaldır. Tamamen farklı karmaşıklık sınıflarında oldukları için bu çözümleri karşılaştırmanın bir yararı yoktur.
dragn

37

Hızlı dizi başlatma sözdizimini de kullanmak yerine, Arrays.asList yöntemini kullanarak hemen benzer bir şekilde Liste olarak başlatabilirsiniz, örneğin:

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

Sonra yapabilirsin (yukarıdaki gibi):

STRINGS.contains("the string you want to find");

35

Java 8 ile bir akış oluşturabilir ve akıştaki herhangi bir girişin eşleşip eşleşmediğini kontrol edebilirsiniz "s":

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

Veya genel bir yöntem olarak:

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

3
İlkel uzmanlıklara da dikkat etmek gerekir.
skiwi

Ayrıca eklemek için anyMatchJavaDoc bunu belirtir, bu "...May not evaluate the predicate on all elements if not necessary for determining the result."nedenle bir eşleşme bulduktan sonra işlemeye devam etmesi gerekmeyebilir.
mkobit

28

Değer için ikili arama yapmak üzere Arrays sınıfını kullanabilirsiniz . Diziniz sıralanmamışsa, diziyi sıralamak için aynı sınıftaki sıralama işlevlerini kullanmanız ve ardından onu aramanız gerekir.


Bunu yapmak için aynı sınıftaki sıralama işlevlerini kullanabilirsiniz ... Bunu cevabıma eklemeliyim.
Thomas Owens

1
Muhtemelen asList (). İçerir () yaklaşımından daha pahalıya mal olacak, o zaman sanırım. Bu kontrolü çok sık yapmanız gerekmedikçe (ancak başlangıç ​​olarak sıralanabilecek statik bir değer listesi ise, adil olmak gerekirse).
Joey

Doğru. En etkili olabilecek birçok değişken vardır. Yine de seçeneklere sahip olmak iyidir.
Thomas Owens

Burada bunu yapan bazı kodlar: stackoverflow.com/a/48242328/9131078
OOBalance

Tüm diziyi arama amacıyla sıralamak pahalıdır. Liner araması için aynı CPU zamanını kullanabiliriz. Önceden sıralı olarak oluşturulmuş bir koleksiyonda ikili aramayı tercih ederim.
arunwithasmile

17

ObStupidAnswer (ama burada bir yerde bir ders olduğunu düşünüyorum):

enum Values {
    AB, BC, CD, AE
}

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

1
İstisna atma görünüşte ağırdır, ancak eğer işe yararsa bir değeri test etmenin yeni bir yolu olacaktır. Dezavantajı, enumun önceden tanımlanması gerektiğidir.
James P.

13

Aslında, Tom Hawtin'in önerdiği gibi HashSet <String> kullanıyorsanız, sıralama konusunda endişelenmenize gerek yoktur ve hızınız, önceden belirlenmiş bir dizide ikili arama ile aynıdır, muhtemelen daha da hızlıdır.

Her şey kodunuzun açık bir şekilde nasıl ayarlandığına bağlıdır, ancak durduğum yerden sipariş şu şekilde olacaktır:

Üzerinde sıralanmamış dizisi:

  1. HashSet
  2. asList
  3. sırala ve ikili

Sıralı bir dizide:

  1. HashSet
  2. İkili
  3. asList

Her iki şekilde de, HashSet kazanmak için.


2
HashSet üyeliği O (1) olmalı ve sıralı bir koleksiyondaki ikili arama O (log n) olmalıdır.
Skylar Saveland

11

Google koleksiyon kitaplığınız varsa Tom'un yanıtı ImmutableSet (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html) kullanılarak çok basitleştirilebilir.

Bu, önerilen başlatma işleminden çok fazla karmaşayı ortadan kaldırır

private static final Set<String> VALUES =  ImmutableSet.of("AB","BC","CD","AE");

10

Olası bir çözüm:

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

8

Geliştiriciler genellikle şunları yapar:

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);

Yukarıdaki kod çalışır, ancak önce bir listeyi ayarlamak için dönüştürmeye gerek yoktur. Bir listeyi sete dönüştürmek fazladan zaman gerektirir. Bu kadar basit olabilir:

Arrays.asList(arr).contains(targetValue);

veya

   for(String s: arr){
        if(s.equals(targetValue))
            return true;
    }

return false;

Birincisi ikincisinden daha okunabilir.


7

Basit bir döngü kullanmak bunu yapmanın en etkili yoludur.

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

Programcreek izniyle


Dizi hedef değerden önce bir boş başvuru içeriyorsa, bu bir boş işaretçi istisnası atar.
Samuel Edwin Ward

1
if ifadesi şöyle olmalıdır: if (targetValue.equals (s)) çünkü String eşittir bir instanceof denetleyicisine sahiptir.
Archon

bunun yerine null güvenli olmak için Objects.equals (obj1, obj2) kullanın.
Üçleme

7

In Java 8 Akışları kullanın.

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

7
Bu yaklaşımın herhangi bir avantajı var mı?
Johannes Stadler

1
Bu soruya cevap vermiyor.
Florian F

5
  1. Sınırlı uzunlukta diziler için aşağıdakileri kullanın ( camickr tarafından verildiği gibi ). Bu, özellikle daha uzun diziler için tekrarlanan kontroller için yavaştır (doğrusal arama).

     Arrays.asList(...).contains(...)
  2. Daha büyük bir eleman setini tekrar tekrar kontrol ederseniz hızlı performans için

    • Dizi yanlış yapıdır. A öğesini kullanın TreeSetve her öğeyi buna ekleyin. Elemanları sıralar ve hızlı bir exist()metoda sahiptir (ikili arama).

    • Elemanlar uygulanırsa Comparableve TreeSetbuna göre sıralanmak istiyorsanız :

      ElementClass.compareTo()yöntemi aşağıdakilerle uyumlu olmalıdır ElementClass.equals(): bkz. Triadlar savaşmaya gelmiyor mu? (Java Seti'nde bir öğe eksik)

      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));
    • Aksi takdirde, kendiniz kullanın 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);
    • Kazanç: bazı unsurların varlığını kontrol edin:

      // Fast binary search through sorted elements (performance ~ log(size)):
      boolean containsElement = myElements.exists(someElement);

4
Neden rahatsız oluyorsun TreeSet? HashSetdaha hızlıdır (O (1)) ve sipariş gerektirmez.
Sean Owen

4

Bunu dene:

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

4

Aşağıdakileri kullanın ( contains()yöntem ArrayUtils.in()bu koddadır):

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

}

Yukarıdaki kodda da görebileceğiniz gibi, başka yardımcı yöntemler de vardır ObjectUtils.equals()ve ArrayUtils.indexOf()bunlar başka yerlerde de kullanılmıştır.


Bu tartışmaya katılmak için çok geç kaldım, ancak bu sorunu çözme yaklaşımım, birkaç yıl önce karşılaştığımda, burada yayınlanan diğer cevaplardan biraz farklı olduğundan, o zaman kullandığım çözümü gönderiyorum, Herkesin faydalı bulması durumunda.
Abhishek Oza

3

Şuna göz at

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

1
Bu işe yaramaz - eşleşmeyen her öğe elseiçin değerini girer (bu nedenle bu dizide "AB" arıyorsanız, 3 kez oraya gider, çünkü değerlerin 3'ü "AB" ").
Bernhard Barker

3

Arrays.asList () -> sonra include () yöntemini çağırmak her zaman işe yarayacaktır, ancak dizi etrafında hafif bir liste sarmalayıcısı oluşturmanız gerekmediğinden bir arama algoritması çok daha iyidir, bu da Arrays.asList () 'in yaptığı şeydir .

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.asListO (n) değildir. Sadece hafif bir ambalaj. Uygulamaya bir göz atın.
Patrick Parker

3

Büyük / küçük harfe duyarlı olmasını istemiyorsanız

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

2

Array.BinarySearch(array,obj)Dizide verilen nesneyi bulmak için kullanın .

Misal:

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

yanlış - mevcut değil


4
Array.BinarySearchve Array.FindIndex.NET yöntemleridir ve Java'da yoktur.
ataylor

@ataylor Java'da Arrays.binarySearch var. Ama haklısın, Arrays.findIndex yok
mente

Dikkat edilmelidir:The array must be sorted prior to making this call. If it is not sorted, the results are undefined.
Dorian Gray

1

Başlangıçta false olarak ayarlanmış bir boolean oluşturun. Dizideki her değeri kontrol etmek ve kontrol ettiğiniz değerle karşılaştırmak için bir döngü çalıştırın. Bir eşleşme alırsanız, boolean değerini true olarak ayarlayın ve döngüyü durdurun. Sonra boolean'ın doğru olduğunu iddia edin.


1

Java 8 yüklem test yöntemini kullanmayı deneyin

İşte bunun tam bir örneği.

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


0

bir kullanımı Spliterator , bir 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 == truesearchdizide yer alıyorsa


Bu does ilkelle diziler için çalışma

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


-2

İki yöntemle kontrol edebilirsiniz

A) Diziyi dizeye dönüştürüp gerekli dizeyi .contains yöntemiyle kontrol ederek

 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) bu daha etkili bir yöntemdir

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

    }

1
Dize dönüşümü saçma derecede verimsizdir ve çözüm yanlıştır, örneğin, (",") içerir, true değerini döndürür.
Atuos
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.