Java'nın Array indexOf'u nerede?


199

Çok açık bir şey eksik olmalı, ama her yerde aradım ve bu yöntemi bulamıyorum.

Yanıtlar:


234

ArraysUtility sınıfını kullanarak bunu başarmanın birkaç yolu vardır .

Dizi sıralanmamışsa ve temel öğeler dizisi değilse :

java.util.Arrays.asList(theArray).indexOf(o)

Dizi halinde olan ilkel değil sıralanmış, bir gibi diğer cevaplar biri tarafından sunulan bir çözüm kullanmalıdır Kerem Baydoğan adlı , Andrew McKinlay en ya Mishax en . Yukarıdaki kod theArrayilkel olsa bile derlenir (muhtemelen bir uyarı verir), ancak yine de tamamen yanlış sonuçlar alırsınız.

Dizi sıralanırsa, performans için ikili aramayı kullanabilirsiniz:

java.util.Arrays.binarySearch(theArray, o)

3
Bu cevabın en azından java 1.6 için yanlış olduğundan eminim: download.oracle.com/javase/6/docs/api/java/util/… asList, argümanlar listesini argümanın kendisine değil bir listeye dönüştürür.
Alexandru

11
@Alexandru Elips kullanımı sözdizimsel şekerdir. Yazılan bir bağımsız değişkeniniz varsa, bağımsız değişkenin T...gerçek çalışma zamanı türü: T[]sıfır veya daha fazla tür parametresinin Tiletilmesi, bunların yeni oluşturulmuş bir diziye sarılmasına ve geçirilmesine neden olur. Geçirilen parametre zaten T[]tipteyse, sözdizimsel şeker atlanır.
Jeffrey Hantin

7
Senin değinmek istediğin noktayı anlıyorum. Çözelti ( .indexOf) temel ilkeler için geçerli değildir.
Alexandru

53
Kimseden bahsetmediği için: Arrays.asList mevcut diziyi destek olarak kullanır. (Yani, bir kopyanın oluşturulmasından endişe edilmez.)
Joshua Goldberg

4
@Notinlist Java adamları da bunu düşündü. Arrays.toList(list).sublist(from,to).indexOf(o)Aralık içindeki bir öğeyi aramak için kullanın [from, to).
Mario Carneiro

62

Dizinin indexOf()yöntemi yoktur .

Belki de bu Apache Commons Lang ArrayUtilsyöntemi aradığınız şeydir

import org.apache.commons.lang3.ArrayUtils;

String[] colours = { "Red", "Orange", "Yellow", "Green" };

int indexOfYellow = ArrayUtils.indexOf(colours, "Yellow");

Eclipse bu içe aktarma kütüphanesini bulamıyor.
Omore

21

Boksu kaçınmak istiyorsanız ilkel için, Guava ilkel dizilerdeki örn için yardımcıları vardır Ints.indexOf (int [] dizi int hedef)


Diğer çözümlerin tümü yeni dizeler veya listeler oluşturur veya yalnızca tek öğeleri işler. Guava'nın Chars.indexOf dizisindeki bir dizinin dizinini almanızı sağlar. Bu doğru çözüm.
HappyEngineer

18

Hiç yok. Ya java.util.List* kullanın ya da kendinizinkini yazabilirsiniz indexOf():

public static <T> int indexOf(T needle, T[] haystack)
{
    for (int i=0; i<haystack.length; i++)
    {
        if (haystack[i] != null && haystack[i].equals(needle)
            || needle == null && haystack[i] == null) return i;
    }

    return -1;
}

* kullanarak dizinizden bir tane yapabilirsiniz Arrays#asList()


2
Kullanımı Tyanıltıcıdır. Herhangi bir tip güvenlik sağlamaz, hata yapması kolay tip güvenlidir ... daha iyi kullanım Nesne
Venkata Raju

4
@VenkataRaju, burada T kullanmak her iki yöntem parametresini de aynı tipte olmaya zorlar. Bu yararlı.
gonadarian

5
@gonadarian Pek değil. Gayet güzel bu derlemesinin ikisi: indexOf("str", new Object[] {});,indexOf(new Object(), new String[] {});
Venkata Raju

1
@VenkataRaju Evet gerçekten. Örneğiniz, bir String bir Nesne olduğu için hiçbir şey kanıtlamaz ... bu nedenle açıkça bir Object dizisi, dizinini bulmak isteyebileceğiniz bir String içerebilir.

1
@ ghert85 Başka bir örnek: indexOf("str", new Date[] {}),indexOf(new Date(), new String[] {})
Venkata Raju

15

Array.IndexOf yöntemine sahip olduğunuz C # ve indexOf yöntemine sahip olduğunuz JavaScript'in aksine , Java API'sı ( özellikle Arrayve Arrayssınıfları) böyle bir yönteme sahip değildir.

Bu yöntem indexOf (tamamlayıcısı lastIndexOf ile birlikte) java.util.List arabiriminde tanımlanır . İndexOf ve lastIndexOf'un aşırı yüklenmediğini ve yalnızca bir Object'i parametre olarak aldığını unutmayın.

Diziniz sıralanırsa , şanslısınız çünkü Arrays sınıfı, aradığınız öğenin dizinini O (n yerine mümkün olan en iyi performansla (O (log n)) bulan bir dizi aşırı yükleme tanımladı. ), ikincisi indexOf tarafından yapılan sıralı bir aramadan bekleyebileceğiniz şeydir). Dört husus vardır:

  1. Dizi ya doğal sırayla ya da bağımsız değişken olarak sağladığınız bir Karşılaştırıcı sırasında ya da en azından anahtarın dizideki öğeden önce gelen tüm öğelerin ve tüm öğelerin önüne gelmesi gerekir. "büyüktür" anahtar dizideki öğeden sonra gelmelidir;

  2. Dizide bir anahtar olup olmadığını belirlemek için normalde indexOf ile yaptığınız test (dönüş değerinin -1 olmadığını doğrulayın) binarySearch ile tutmaz. Döndürülen değer, anahtarın bulunmadığını, ancak varsa beklenen dizini göstereceğinden, dönüş değerinin sıfırdan küçük olmadığını doğrulamanız gerekir;

  3. Diziniz anahtara eşit birden çok öğe içeriyorsa, binarySearch'ten aldığınız şey tanımsızdır; bu, ilk örneği döndürecek indexOf ve son örneği döndürecek lastIndexOf öğelerinden farklıdır.

  4. Bir dizi booleans, önce tüm yanlışları ve sonra tüm trues'leri içeriyorsa sıralanmış gibi görünebilir, ancak bu sayılmaz. Bir dizi booleans dizisini kabul eden binarySearch yönteminin geçersiz kılınması yoktur ve bir dizide ilk true'nun nerede göründüğünü algılarken, örneğin bir dizi kullanarak Boolean'lar ve sabitleri Boolean.FALSE ve Boolean.TRUE.

Diziniz sıralanmamışsa ve ilkel tür değilse , java.util.Arrays öğesinin asList yöntemini çağırarak List'in indexOf ve lastIndexOf yöntemlerini kullanabilirsiniz . Bu yöntem, dizinizin çevresinde bir AbstractList arabirimi sarmalayıcısı döndürür. Dizinin bir kopyasını oluşturmadığı için minimum ek yük içerir. Belirtildiği gibi, bu yöntem aşırı yüklenmez, bu nedenle bu yalnızca referans türlerinin dizileri üzerinde çalışır.

Diziniz sıralanmamışsa ve dizinin türü ilkel ise, Java API'sında şansınız kalmamıştır . Döngü için kendinize veya bir nesne örneğinin ek yükünü içeren asList yaklaşımına göre performans avantajlarına sahip olacak kendi statik yardımcı yönteminizi yazın. Dizinin tüm öğeleri üzerinde yinelenen döngü için kaba bir kuvvet yazmanın zarif bir çözüm olmadığından endişe ediyorsanız, indexOf'u çağırdığınızda Java API'sinin tam olarak bunu yaptığını kabul edin. Bunun gibi bir şey yapabilirsiniz:

public static int indexOfIntArray(int[] array, int key) {
    int returnvalue = -1;
    for (int i = 0; i < array.length; ++i) {
        if (key == array[i]) {
            returnvalue = i;
            break;
        }
    }
    return returnvalue;
}

Burada kendi yönteminizi yazmaktan kaçınmak istiyorsanız, Guava gibi bir geliştirme çerçevesinden birini kullanmayı düşünün. Orada indexOf ve lastIndexOf'un bir uygulamasını bulabilirsiniz .


11

Java'nın ArrayListbir indexOfyöntemi vardır. Java dizilerinin böyle bir yöntemi yoktur.


26
Sadece ArrayList- Her Java Listsahiptir indexOf().
Matt Ball

6

Diziniz ilkel türler içeriyorsa , muhtemelen birçok java.util.Arrays#binarySearch(...)yöntemden birini ( Arrays javadoc bakın ) kullanabilirsiniz, ancak kendiniz için kodlama dışında dizilerde bir "indexOf" hatırlamıyorum ...


5

Liste arabiriminin bir indexOf () yöntemi vardır ve dizinizden Array'ın asList () yöntemiyle bir Liste alabilirsiniz. Bunun dışında, Array'ın böyle bir yöntemi yoktur. Sıralı diziler için bir binarySearch () yöntemi vardır.


4

Dizilerin kendilerinin bu yöntemi yoktur. Ancak bir Liste şunu yapar: indexOf


2
Sadece ArrayList- Her Java Listsahiptir indexOf().
Matt Ball

Evet, ArrayList'i yeni belirledim çünkü OP'nin aradığı şeylere en yakın şey bu olabilir :)
Igor


2

Java dizilerinde doğrudan indexOf işlevi yoktur.


0

Jeffrey Hantin'in cevabı iyi ama bazı kısıtlamaları var, eğer bunu bu ya da başka bir şey yaparsa ...

Kendi uzatma yönteminizi yazabilirsiniz ve her zaman istediğiniz şekilde çalışır.

Lists.indexOf(array, x -> item == x); // compare in the way you want

Ve işte uzantınız

public final class Lists {
    private Lists() {
    }

    public static <T> int indexOf(T[] array, Predicate<T> predicate) {
        for (int i = 0; i < array.length; i++) {
            if (predicate.test(array[i])) return i;
        }
        return -1;
    }

    public static <T> int indexOf(List<T> list, Predicate<T> predicate) {
        for (int i = 0; i < list.size(); i++) {
            if (predicate.test(list.get(i))) return i;
        }
        return -1;
    }

    public interface Predicate<T> {
        boolean test(T t);
    }
}

-4
int findIndex(int myElement, int[] someArray){
 int index = 0;
 for(int n: someArray){
   if(myElement == n) return index;
   else index++;
 }
}

Not: Bu yöntemi int türündeki diziler için kullanabilirsiniz, bu algoritmayı küçük değişikliklere sahip diğer türler için de kullanabilirsiniz


1
-1: İlk önce bu, sıralanmayacağımız orijinal diziyi değiştirir. İkincisi, istediğimiz şey olan orijinal diziyi değil, sıralı diziyi yanıtı verir (eğer cevabı wrt sıralı diziyi isteseydik, zaten sıralanırdı). Üçüncüsü, sıralama O (n log n) olduğundan, bu sadece diziden doğrusal olarak geçmekten daha yavaştır. Yani bu cevap hem yanlış hem de verimsiz.
Jamie

yerinde dizin kullanıldığında orijinal dizin kaybedildi.
Downhillski
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.