Java的数组indexOf在哪里?

246

我一定漏掉了什么非常明显的东西,但我已经四处搜寻,找不到这个方法。

13个回答

272
使用Arrays实用类有几种方法可以实现此目标。
如果数组未排序且不是基元素数组:
java.util.Arrays.asList(theArray).indexOf(o)

如果数组是原始类型且未排序,则应使用其他答案中提供的解决方案,例如Kerem BaydoğanAndrew McKinlayMishax。即使theArray是原始类型(可能会发出警告),上述代码也将编译,但您仍将得到完全不正确的结果。
如果数组已排序,则可以利用二进制搜索来提高性能:
java.util.Arrays.binarySearch(theArray, o)

4
我十分确定,至少对于Java 1.6来说,以下答案是错误的:http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#asList(T...) asList将参数列表转换为列表,而不是参数本身。 - Alexandru
11
Ellipsis处理是一种语法糖。如果你有一个类型为T...的参数,实际运行时该参数的类型是T[],传递零个或多个类型为T的参数会将它们包装到一个新构造的数组中并传递。如果要传递的参数已经是T[]类型,则会绕过这种语法糖。 - Jeffrey Hantin
9
我明白你的意思。然而,对于基本数据类型来说,解决方案(.indexOf)是无效的。 - Alexandru
59
没有人提到:Arrays.asList使用已经存在的数组作为支持。也就是说,不必担心会创建副本。 - Joshua Goldberg
4
Java开发者也考虑了这一点。使用Arrays.toList(list).sublist(from,to).indexOf(o)在范围[from, to)内搜索元素。 - Mario Carneiro
显示剩余8条评论

79

数组没有indexOf()方法。

也许你要找的是这个Apache Commons LangArrayUtils方法。

import org.apache.commons.lang3.ArrayUtils;

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

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

Eclipse 找不到该导入库。 - Omore

22

对于原始数据类型,如果想避免装箱操作,Guava提供了原语数组的帮助类例如Ints.indexOf(int[] array, int target)


其他解决方案都会创建新的字符串或列表,或者只处理单个元素。Guava的Chars.indexOf允许您获取数组中另一个数组的索引。这是正确的解决方案。 - HappyEngineer

20

这里没有单独的方法。您可以使用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;
}

*你可以使用Arrays#asList()从你的数组中创建一个。


4
使用 T 是具有误导性的。它并没有提供任何类型安全性,很容易被误认为是类型安全的...最好使用 Object。 - Venkata Raju
4
@VenkataRaju,使用 T 这个参数可以强制让两个方法参数的类型相同。这很有用。 - gonadarian
7
不是很复杂。这两个都可以正常编译:indexOf("str", new Object[] {});indexOf(new Object(), new String[] {}); - Venkata Raju
1
@VenkataRaju 是的,真的。你的例子并没有证明什么,因为String是一个对象...所以显然一个对象数组可以包含你想要找到索引的字符串。 - user7917402
4
另一个例子:indexOf("str", new Date[] {})indexOf(new Date(), new String[] {})。 这两个示例中,第一个是在一个空的日期数组中查找字符串"str"的索引位置,第二个是在一个空的字符串数组中查找日期对象的索引位置。 - Venkata Raju
它不能与原始类型一起使用。 - Hasen

20
不同于C#中的Array.IndexOf方法和JavaScript中的indexOf方法,Java的API(特别是ArrayArrays类)没有这样的方法。
这个indexOf方法(以及它的补充lastIndexOf)在java.util.List接口中定义。请注意,indexOf和lastIndexOf没有重载,并且只接受一个对象作为参数。 如果你的数组已经排序了,那么你很幸运,因为Arrays类定义了一系列的binarySearch方法重载,可以以最佳性能(O(log n)而不是O(n),后者是你从indexOf方法进行的顺序搜索所期望的)找到你要查找的元素的索引。有四个要考虑的问题:
  1. 数组必须按照自然顺序或您提供的比较器的顺序排序,或者至少所有“小于”关键字的元素必须在数组中该元素之前出现,所有“大于”关键字的元素必须在数组中该元素之后出现;

  2. 您通常使用indexOf进行测试以确定关键字是否在数组中(验证返回值是否不为-1),但是在二进制搜索中,这个测试不起作用。您需要验证返回值是否小于零,因为返回的值将指示关键字不存在,但如果存在,它将预期在哪个索引位置。

  3. 如果数组中包含多个与关键字相等的元素,则从binarySearch中获得的结果是未定义的。这与indexOf不同,后者将返回第一个出现的位置,而lastIndexOf将返回最后一个出现的位置。

  4. 如果数组中包含布尔值,则可能会出现已排序的情况,如果首先包含所有false,然后包含所有true,但这不算数。没有覆盖接受布尔数组的binarySearch方法,如果要在数组中检测第一个true出现的位置并获得O(log n)性能,您将不得不做一些聪明的事情,例如使用Booleans数组和Boolean.FALSE和Boolean.TRUE常量。

如果您的数组未排序且不是原始类型,您可以通过调用java.util.Arrays的asList方法使用List的indexOf和lastIndexOf方法。该方法将返回一个围绕您的数组的AbstractList接口包装器。它涉及最小的开销,因为它不会创建数组的副本。如上所述,此方法未重载,因此仅适用于引用类型的数组。
如果您的数组未排序且数组类型是原始类型,则无法使用Java API。编写自己的for循环或自己的静态实用程序方法,这肯定比涉及某些对象实例化开销的asList方法更具性能优势。如果您担心编写一个暴力for循环来迭代数组的所有元素不是一种优雅的解决方案,请接受当您调用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的实现。

14

Java ArrayList 有一个 indexOf 方法。而 Java 数组就没有这样的方法。


31
不仅仅是 ArrayList - 每个 Java 的 List 都有 indexOf() 方法。 - Matt Ball

7

我记不得除了自己编写之外,在数组上是否有“indexOf”方法...但是如果您的数组包含原始类型,您可能可以使用众多的java.util.Arrays#binarySearch(...)方法之一(请参见Arrays javadoc)。


5

数组本身没有这个方法。然而,List有: indexOf


3
不仅是ArrayList - 每个Java List 都有 indexOf() 方法。 - Matt Ball
是的,我只是指定了ArrayList,因为那可能是最接近OP所寻找的东西 :) - Igor

5

List接口有一个indexOf()方法,你可以使用Array的asList()方法从数组中获取List。除此之外,Array本身没有这样的方法。它确实有一个用于排序数组的binarySearch()方法。


3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接