Java的Array indexOf在哪里?

Jam*_*mie 183 java arrays indexof

我必须遗漏一些非常明显的东西,但我已经搜遍了所有并且找不到这种方法.

Jef*_*tin 219

使用Arrays实用程序类有两种方法可以实现此目的.

如果数组未排序且不是基元数组:

java.util.Arrays.asList(theArray).indexOf(o)
Run Code Online (Sandbox Code Playgroud)

如果数组基元并且没有排序,那么应该使用其他答案之一提供的解决方案,例如KeremBaydoğan,Andrew McKinlayMishax.即使theArray是原始代码(可能发出警告),上面的代码也会编译,但是你会得到完全错误的结果.

如果数组已排序,您可以使用二进制搜索来获得性能:

java.util.Arrays.binarySearch(theArray, o)
Run Code Online (Sandbox Code Playgroud)

  • 由于没有人提到:Arrays.asList使用已经存在的数组作为支持.(即不关心正在创建的副本.) (51认同)
  • @Alexandru Ellipsis处理是语法糖.如果你有一个参数类型为"T ...",那么参数的实际运行时类型是`T []`,并且传递零个或多个类型为"T"的参数会导致它们被包装到一个新构造的数组中并通过.如果传递的参数已经是`T []`类型,则绕过语法糖. (10认同)
  • 我明白你的意思了.但是,解决方案(`.indexOf`)对于基元无效. (6认同)
  • @Notinlist java家伙也想到了这一点.使用`Arrays.toList(list).sublist(from,to).indexOf(o)`来搜索`[from,to]`范围内的元素. (3认同)
  • 我很确定这个答案至少对java 1.6来说是错误的:http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#asList(T ...)asList转换列表中的参数列表而不是参数本身. (2认同)
  • @Jeffrey:拳击不适用于数组,仅适用于单个值.(另外,你通常不希望"动态"转换整个数组.最好在你的原始数组周围有一些列表包装.) (2认同)

Ker*_*ğan 59

数组没有indexOf()方法.

也许这个Apache Commons Lang ArrayUtils方法就是你想要的

import org.apache.commons.lang3.ArrayUtils;

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

int indexOfYellow = ArrayUtils.indexOf(colours, "Yellow");
Run Code Online (Sandbox Code Playgroud)


Mat*_*all 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;
}
Run Code Online (Sandbox Code Playgroud)

*您可以使用您的阵列制作一个 Arrays#asList()

  • @gonadarian不是真的.这两个编译都很好:`indexOf("str",new Object [] {});`,`indexOf(new Object(),new String [] {});` (5认同)
  • @VenkataRaju,使用T强制两个方法参数属于同一类型.那很有用. (4认同)
  • @ghert85 另一个例子:`indexOf("str", new Date[] {})`, `indexOf(new Date(), new String[] {})` (3认同)
  • 使用`T`会产生误导.它不提供任何类型的安全性,容易误认为它是类型安全的......更好地使用Object (2认同)

And*_*lay 17

对于原语,如果你想避免装箱,Guava有原始数组的助手,例如Ints.indexOf(int [] array,int target)


Mis*_*hax 13

与C#中的Array.IndexOf方法和使用indexOf方法的JavaScript不同,Java的API(特别是ArrayArrays类)没有这样的方法.

此方法indexOf(及其补码lastIndexOf)在java.util.List接口中定义.请注意,indexOf和lastIndexOf不会重载,只会将Object作为参数.

如果您的数组已排序,那么您很幸运,因为Arrays类定义了binarySearch方法的一系列重载,它将找到您正在寻找的元素的索引,具有最佳性能(O(log n)而不是O(n ),后者是你对indexOf完成的顺序搜索所期望的.有四个注意事项:

  1. 数组必须按照自然顺序或按照作为参数提供的比较器的顺序进行排序,或者至少所有"小于"键的元素必须位于数组中的该元素之前,并且所有元素都必须是"大于"键必须在数组中的元素之后;

  2. 您通常使用indexOf来确定某个键是否在数组中(验证返回值是否为-1)的测试不适用于binarySearch.您需要验证返回值是否不小于零,因为返回的值将指示密钥不存在,但是如果密钥存在则将指向该索引;

  3. 如果你的数组包含多个与键相同的元素,你从binarySearch获得的是未定义的; 这与将返回第一个匹配项的indexOf和将返回最后一个匹配项的lastIndexOf不同.

  4. 如果一个布尔值首先包含所有的谬误,然后是所有的诅咒,那么它可能会被排序,但这不算数.没有覆盖接受布尔数组的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;
}
Run Code Online (Sandbox Code Playgroud)

如果您想避免在此处编写自己的方法,请考虑使用像Guava这样的开发框架中的方法.在那里你可以找到indexOflastIndexOf的实现.


Jam*_*mes 11

Java ArrayList有一种indexOf方法.Java数组没有这样的方法.

  • 不仅仅是`ArrayList` - 每个Java`List`都有`indexOf()`. (25认同)

Kel*_*dil 6

我不记得数组上的"indexOf"而不是自己编码...虽然如果你的数组包含基本类型,你可能会使用众多java.util.Arrays#binarySearch(...)方法之一(参见Arrays javadoc)


Igo*_*gor 5

数组本身没有这个方法。然而,列表可以: indexOf

  • 不仅仅是 `ArrayList` - 每个 Java `List` 都有 `indexOf()`。 (3认同)

Mik*_*key 5

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