Javaの配列indexOfはどこにありますか?


198

私は非常に明白な何かを見逃しているに違いありませんが、私は至る所を検索しましたが、この方法を見つけることができません。

回答:


234

Arraysユーティリティクラスを使用してこれを実現するには、いくつかの方法があります。

配列がソートされておらず、プリミティブの配列でもない場合:

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

配列がいる場合、プリミティブとないソート、1のような他の回答の一つが提供するソリューションを使用する必要がありケレムBaydoğanさんアンドリュー・マッキンリーのMishaxのを。上記のコードtheArrayはプリミティブ(おそらく警告を発する)であってもコンパイルされますが、それでも完全に誤った結果が得られます。

配列がソートされている場合は、パフォーマンスのためにバイナリ検索を利用できます。

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

3
この答えが少なくともJava 1.6では間違っていると確信しています。download.oracle.com/ javase / 6 / docs / api / java / util /…asListは、引数のリストを引数自体ではなくリストに変換します。
Alexandru

11
@Alexandru Ellipsisの処理は構文糖衣です。引数がtypedの場合、引数T...の実際の実行時の型はであり、typeのT[]0個以上のパラメーターを渡すとT、新しく構築された配列にラップされて渡されます。渡されるパラメーターが既にtype型であるT[]場合、構文糖衣はバイパスされます。
ジェフリーハンティン2011年

7
あなたの言ってる事がわかります。.indexOfただし、ソリューション()はプリミティブには無効です。
Alexandru

53
誰も言及していないため:Arrays.asListは、既存の配列をバッキングとして使用します。(つまり、コピーが作成される心配はありません。)
Joshua Goldberg

4
@Notinlist Javaの人達もそう考えました。Arrays.toList(list).sublist(from,to).indexOf(o)範囲内の要素を検索するために使用します[from, to)
マリオカルネイロ2016年

62

配列にはindexOf()メソッドがありません。

多分このApache Commons Lang ArrayUtilsメソッドはあなたが探しているものです

import org.apache.commons.lang3.ArrayUtils;

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

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

Eclipseはこのインポートライブラリを見つけられません。
オモア2017年

21

プリミティブの場合、ボックス化を避けたい場合、Guavaにはプリミティブ配列のヘルパーがあります。たとえば、Ints.indexOf(int [] array、int target)


他のソリューションはすべて、新しい文字列またはリストを作成するか、単一の要素を処理します。GuavaのChars.indexOfを使用すると、配列内の配列のインデックスを取得できます。これが正しい解決策です。
HappyEngineer 2016年

18

なにもない。java.util.List*を使用するか、独自に記述できます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;
}

*あなたはあなたの配列から1つを作ることができます Arrays#asList()


2
使用Tは誤解を招くものです。タイプセーフは提供されず、タイプセーフであると間違えやすい...オブジェクトの使用が改善される
Venkata Raju

4
@VenkataRaju、ここでTを使用すると、両方のメソッドパラメーターが同じタイプになります。それは便利です。
生殖腺

5
@gonadarianそうではない。うまくこれらのコンパイルの両方:indexOf("str", new Object[] {});indexOf(new Object(), new String[] {});
ヴェンカタラジュ

1
@VenkataRajuはい、そうです。文字列はオブジェクトなので、例では何も証明されません...明らかに、オブジェクト配列には、インデックスを検索したい文字列を含めることができます。

1
@ ghert85別の例:indexOf("str", new Date[] {})indexOf(new Date(), new String[] {})
Venkata Raju

15

Array.IndexOfメソッドがあるC#やindexOfメソッドがあるJavaScript とは異なり、JavaのAPI(特にArrayおよびArraysクラス)にはそのようなメソッドはありません。

このメソッドindexOfは(そのlastIndexOfと一緒に)java.util.Listインターフェースで定義されます。indexOfとlastIndexOfはオーバーロードされず、パラメーターとしてオブジェクトのみを受け取ることに注意してください。

配列がソートされている場合、Arraysクラスは、可能な限り最高のパフォーマンス(O(n)ではなくO(log n)で探している要素のインデックスを見つけるbinarySearchメソッドの一連のオーバーロードを定義しているので、幸運です。 )、後者はindexOfによって行われる順次検索から期待できるものです。4つの考慮事項があります。

  1. 配列は、自然な順序または引数として提供するコンパレータの順序で並べ替える必要があります。または、少なくとも、キーより「小さい」すべての要素が、配列内のその要素の前に来る必要があります。キーが配列のその要素の後に来る必要がある「より大きい」。

  2. キーが配列内にあるかどうかを判別するために通常indexOfで行うテスト(戻り値が-1でないことを確認する)は、binarySearchには当てはまりません。返された値はキーが存在しないことを示しているので、戻り値がゼロ以上であることを確認する必要がありますが、存在した場合に予想されるインデックスです。

  3. キーに等しい複数の要素が配列に含まれている場合、binarySearchから得られるものは未定義です。これは、最初のオカレンスを返すindexOfおよび最後のオカレンスを返すlastIndexOfとは異なります。

  4. ブール値の配列は、最初にすべてのfalse、次にすべてのtrueが含まれている場合、ソートされているように見えますが、これはカウントされません。ブール値の配列を受け入れるbinarySearchメソッドのオーバーライドはありません。たとえば、配列の最初のtrueが配列のどこに現れるかを検出するときにO(log n)パフォーマンスが必要な場合は、そこで賢いことをする必要があります。ブール値と定数Boolean.FALSEおよびBoolean.TRUE。

配列がソートされておらず、プリミティブ型でもない場合、 java.util.ArraysのasListメソッドを呼び出すことにより、ListのindexOfメソッドとlastIndexOfメソッドを使用できます。このメソッドは、配列のAbstractListインターフェイスラッパーを返します。アレイのコピーを作成しないため、オーバーヘッドは最小限です。前述のように、このメソッドはオーバーロードされないため、参照型の配列でのみ機能します。

配列がソートされておらず、配列のタイププリミティブである場合は、Java APIを使用できません。独自のforループ、または独自の静的ユーティリティメソッドを記述します。これらは、オブジェクトのインスタンス化のオーバーヘッドを伴うasListアプローチよりもパフォーマンス上の利点があります。配列のすべての要素を反復するブルートフォースループを作成することがエレガントな解決策ではない場合は、indexOfを呼び出すときにJava APIが実行していることをそのまま受け入れてください。あなたはこのようなものを作ることができます:

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

ここで独自のメソッドを記述したくない場合は、Guavaなどの開発フレームワークからのメソッドの使用を検討してください。そこではindexOflastIndexOfの実装を見つけることができます。


11

Java ArrayListにはindexOfメソッドがあります。Java配列にはそのようなメソッドはありません。


26
だけでなく、ArrayListすべてのJava Listが持っていindexOf()ます。
マットボール

6

自分でコーディングする以外に、配列の「indexOf」を思い出したことはありません...ただし、配列にプリミティブ型が含まれている場合は、多くのjava.util.Arrays#binarySearch(...)メソッドの1つ(配列javadocを参照)を使用できます。


5

ListインターフェースにはindexOf()メソッドがあり、ArrayのasList()メソッドを使用して配列からListを取得できます。それ以外には、Array自体にはそのようなメソッドはありません。ソートされた配列用のbinarySearch()メソッドはありません。


4

配列自体にはそのメソッドはありません。Aリストは、しかし、行います のindexOf


2
だけでなく、ArrayListすべてのJava Listが持っていindexOf()ます。
マットボール

ええ、OPが探していたものに最も近い可能性があるので、ArrayListを指定しました:)
Igor



0

ジェフリー・ハンティンの答えは良いですが、これがこれを行うか、そうでなければそれにはいくつかの制約があります...

あなたはあなた自身の拡張メソッドを書くことができ、それはいつもあなたが望む方法で機能します。

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

そしてここにあなたの拡張があります

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

注:このメソッドはint型の配列に使用できます。このアルゴリズムは、小さな変更を加えた他の型にも使用できます。


1
-1:最初に、これはソートされないようにする元の配列を変更します。2つ目は、元の配列ではなく、ソートされた配列に対する回答を提供します。これは、私たちが望むものである可能性が高いです(ソートされた配列に対する回答が必要な場合は、すでにソートされています)。3つ目は、並べ替えがO(n log n)であるため、配列を直線的に処理するよりも低速です。したがって、この答えは間違っていて非効率的です。
ジェイミー

インプレースソートを使用すると、元のインデックスが失われました。
Downhillski
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.