Di mana indeks Array Java?

198

Saya pasti kehilangan sesuatu yang sangat jelas, tetapi saya telah mencari di seluruh dan tidak dapat menemukan metode ini.

Jamie
sumber

Jawaban:

234

Ada beberapa cara untuk mencapai ini menggunakan Arrayskelas utilitas.

Jika array tidak diurutkan dan bukan array primitif:

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

Jika array adalah primitif dan tidak diurutkan, seseorang harus menggunakan solusi yang ditawarkan oleh salah satu jawaban lain seperti Kerem Baydoğan , Andrew McKinlay's atau Mishax's . Kode di atas akan dikompilasi meskipun theArrayprimitif (mungkin memancarkan peringatan) tetapi Anda akan mendapatkan hasil yang benar-benar salah.

Jika array diurutkan, Anda dapat menggunakan pencarian biner untuk kinerja:

java.util.Arrays.binarySearch(theArray, o)
Jeffrey Hantin
sumber
3
Saya cukup yakin jawaban ini salah setidaknya untuk java 1.6: download.oracle.com/javase/6/docs/api/java/util/... asList mengubah daftar argumen menjadi daftar, bukan argumen itu sendiri.
Alexandru
11
@Alexandru Ellipsis adalah gula sintaksis. Jika Anda memiliki argumen yang diketik T..., tipe run-time sebenarnya dari argumen adalah T[], dan melewati nol atau lebih parameter Thasil tipe di dalamnya yang dibungkus menjadi array yang baru dibangun dan diteruskan. Jika parameter yang dikirimkan sudah bertipe T[], gula sintaksis dilewati.
Jeffrey Hantin
7
Saya mengerti maksud Anda. Solusinya ( .indexOf) tidak berlaku untuk primitif.
Alexandru
53
Karena tidak ada yang menyebutkan: Arrays.asList menggunakan array yang sudah ada sebagai backing. (Yaitu tidak ada masalah tentang salinan yang dibuat.)
Joshua Goldberg
4
@Notinlist Orang-orang java juga memikirkan hal itu. Gunakan Arrays.toList(list).sublist(from,to).indexOf(o)untuk mencari elemen dalam rentang [from, to).
Mario Carneiro
62

Array tidak memiliki indexOf()metode.

Mungkin ArrayUtilsmetode Lang Apache Commons ini adalah apa yang Anda cari

import org.apache.commons.lang3.ArrayUtils;

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

int indexOfYellow = ArrayUtils.indexOf(colours, "Yellow");
Kerem Baydoğan
sumber
Eclipse tidak menemukan perpustakaan impor ini.
Omore
21

Untuk primitif, jika Anda ingin menghindari tinju, Guava memiliki pembantu untuk array primitif misalnya Ints.indexOf ( array int [], target int)

Andrew McKinlay
sumber
Solusi lain semua membuat string atau daftar baru atau hanya menangani elemen tunggal. Guava's Chars.indexOf memungkinkan Anda mendapatkan indeks dari array di dalam array. Ini solusi yang tepat.
HappyEngineer
18

Tidak ada. Baik menggunakan a java.util.List*, atau Anda dapat menulis sendiri 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;
}

* Anda dapat membuatnya dari array menggunakan Arrays#asList()

Matt Ball
sumber
2
Menggunakan Titu menyesatkan. Itu tidak memberikan keamanan jenis apa pun, mudah disalahartikan sebagai tipe aman ... lebih baik gunakan Object
Venkata Raju
4
@VenkataRaju, menggunakan T di sini memaksa kedua parameter metode memiliki tipe yang sama. Itu berguna.
gonadarian
5
@ gonadarian Tidak juga. Kedua kompilasi ini baik-baik saja: indexOf("str", new Object[] {});,indexOf(new Object(), new String[] {});
Venkata Raju
1
@VenkataRaju Ya benar. Contoh Anda tidak membuktikan apa-apa karena sebuah String adalah sebuah Objek ... jadi jelas sebuah array Obyek dapat berisi sebuah String yang Anda mungkin ingin menemukan indeks.
1
@ ghert85 Contoh lain: indexOf("str", new Date[] {}),indexOf(new Date(), new String[] {})
Venkata Raju
15

Tidak seperti di C # di mana Anda memiliki metode Array.IndexOf , dan JavaScript di mana Anda memiliki metode indexOf , API Java ( Arraydan Arrayskelas khususnya) tidak memiliki metode seperti itu.

Metode indexOf ini (bersama dengan pelengkap lastIndexOf) didefinisikan dalam antarmuka java.util.List . Perhatikan bahwa indexOf dan lastIndexOf tidak kelebihan beban dan hanya mengambil Obyek sebagai parameter.

Jika array Anda diurutkan , Anda beruntung karena kelas Array mendefinisikan serangkaian kelebihan metode binarySearch yang akan menemukan indeks elemen yang Anda cari dengan kinerja terbaik (O (log n), bukan O (n ), yang terakhir adalah apa yang dapat Anda harapkan dari pencarian berurutan yang dilakukan oleh indexOf). Ada empat pertimbangan:

  1. Array harus diurutkan baik dalam urutan alami atau dalam urutan pembanding yang Anda berikan sebagai argumen, atau paling tidak semua elemen yang "kurang dari" kunci harus datang sebelum elemen dalam array dan semua elemen yang "lebih besar dari" kunci harus datang setelah elemen dalam array;

  2. Tes yang biasanya Anda lakukan dengan indexOf untuk menentukan apakah kunci dalam array (verifikasi jika nilai kembali bukan -1) tidak berlaku dengan binarySearch. Anda perlu memverifikasi bahwa nilai kembali tidak kurang dari nol karena nilai yang dikembalikan akan menunjukkan kunci tidak ada tetapi indeks di mana itu akan diharapkan jika memang ada;

  3. Jika array Anda mengandung banyak elemen yang sama dengan kunci, apa yang Anda dapatkan dari binarySearch tidak ditentukan; ini berbeda dari indexOf yang akan mengembalikan kejadian pertama dan lastIndexOf yang akan mengembalikan kejadian terakhir.

  4. Array booleans mungkin tampak diurutkan jika pertama-tama berisi semua kesalahan dan kemudian semua tanda, tetapi ini tidak masuk hitungan. Tidak ada penggantian metode binarySearch yang menerima array booleans dan Anda harus melakukan sesuatu yang pintar di sana jika Anda ingin O (log n) kinerja ketika mendeteksi di mana true pertama muncul dalam array, misalnya menggunakan array dari Boolean dan konstanta Boolean.FALSE dan Boolean.TRUE.

Jika array Anda tidak diurutkan dan bukan tipe primitif , Anda dapat menggunakan metode indexOf dan lastIndexOf List dengan memunculkan metode asList dari java.util.Arrays. Metode ini akan mengembalikan pembungkus antarmuka AbstractList di sekitar array Anda. Ini melibatkan overhead minimal karena tidak membuat salinan array. Seperti disebutkan, metode ini tidak kelebihan beban sehingga ini hanya akan bekerja pada array tipe referensi.

Jika array Anda tidak diurutkan dan jenis array adalah primitif , Anda beruntung dengan API Java. Tulis sendiri untuk loop, atau metode utilitas statis Anda sendiri, yang tentunya akan memiliki keunggulan kinerja dibandingkan pendekatan asList yang melibatkan beberapa overhead dari instance objek. Jika Anda khawatir bahwa menulis brute force untuk loop yang berulang pada semua elemen array bukanlah solusi yang elegan, terimalah bahwa itulah yang dilakukan Java API ketika Anda memanggil indexOf. Anda dapat membuat sesuatu seperti ini:

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

Jika Anda ingin menghindari menulis metode Anda sendiri di sini, pertimbangkan untuk menggunakannya dari kerangka pengembangan seperti Jambu. Di sana Anda dapat menemukan implementasi indexOf dan lastIndexOf .

Mishax
sumber
11

Java ArrayListmemiliki indexOfmetode. Array Java tidak memiliki metode seperti itu.

James
sumber
26
Bukan hanya ArrayList- setiap Jawa Listmemiliki indexOf().
Matt Ball
6

Saya tidak ingat "indexOf" pada array selain mengkodekannya sendiri ... meskipun Anda mungkin bisa menggunakan salah satu dari banyak java.util.Arrays#binarySearch(...)metode (lihat javadoc Array ) jika array Anda mengandung tipe primitif

Kellindil
sumber
5

Antarmuka Daftar memiliki metode indexOf (), dan Anda bisa mendapatkan Daftar dari array Anda dengan metode Array's asList (). Selain itu, Array sendiri tidak memiliki metode seperti itu. Itu memang memiliki metode binarySearch () untuk array yang diurutkan.

Mike Yockey
sumber
4

Array sendiri tidak memiliki metode itu. Namun, Daftar tidak: indexOf

Igor
sumber
2
Bukan hanya ArrayList- setiap Jawa Listmemiliki indexOf().
Matt Ball
Ya, saya baru saja menetapkan ArrayList karena itu mungkin hal terdekat dengan apa yang dicari OP :)
Igor
3

Anda mungkin memikirkan java.util.ArrayList , bukan array.

Duffymo
sumber
2

Tidak ada fungsi indexOf langsung di array java.

gambo
sumber
0

Jawaban Jeffrey Hantin baik tetapi memiliki beberapa kendala, apakah ini yang dilakukan atau tidak ...

Anda dapat menulis metode ekstensi sendiri dan selalu bekerja seperti yang Anda inginkan.

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

Dan inilah ekstensi Anda

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);
    }
}
M.kazem Akhgary
sumber
-4
int findIndex(int myElement, int[] someArray){
 int index = 0;
 for(int n: someArray){
   if(myElement == n) return index;
   else index++;
 }
}

Catatan: Anda dapat menggunakan metode ini untuk array bertipe int, Anda juga dapat menggunakan algoritme ini untuk jenis lain dengan perubahan kecil

vivek gupta
sumber
1
-1: Pertama-tama, ini akan mengubah array asli untuk diurutkan yang mungkin tidak kita inginkan. Kedua, berikan jawaban wrt array yang diurutkan, bukan array asli yang kemungkinan kita inginkan (jika kita ingin jawaban wrt array yang diurutkan, itu sudah akan diurutkan). Ketiga karena pengurutan adalah O (n log n) ini lebih lambat daripada hanya melalui array secara linear. Jadi jawaban ini salah dan tidak efisien.
Jamie
indeks asli hilang ketika jenis di tempat digunakan.
Downhillski