Java 的数组 indexOf 在哪里?
Posted
技术标签:
【中文标题】Java 的数组 indexOf 在哪里?【英文标题】:Where is Java's Array indexOf? 【发布时间】:2011-06-25 03:27:29 【问题描述】:我一定是遗漏了一些很明显的东西,但是我已经搜索了一遍,找不到这个方法。
【问题讨论】:
【参考方案1】:有几种方法可以使用Arrays
实用程序类来完成此操作。
如果数组未排序且不是基元数组:
java.util.Arrays.asList(theArray).indexOf(o)
如果数组 是 原语且未排序,则应使用其他答案之一提供的解决方案,例如 Kerem Baydoğan's、Andrew McKinlay's 或 Mishax's。即使theArray
是原始的(可能发出警告),上面的代码也会编译,但您仍然会得到完全不正确的结果。
如果数组已排序,则可以使用二分查找来提高性能:
java.util.Arrays.binarySearch(theArray, o)
【讨论】:
我很确定这个答案至少对于 java 1.6 来说是错误的:download.oracle.com/javase/6/docs/api/java/util/… asList 将参数列表转换为列表而不是参数本身。 @Alexandru Ellipsis 处理是语法糖。如果您有一个类型为T...
的参数,则该参数的实际运行时类型是T[]
,并且传递零个或多个T
类型的参数会导致它们被包装到一个新构造的数组中并传递。如果传递的参数已经是 T[]
类型,则绕过语法糖。
我明白你的意思。不过,解决方案 (.indexOf
) 对基元无效。
由于没有人提到:Arrays.asList 使用已经存在的数组作为支持。 (即无需担心创建副本。)
@Notinlist Java 人也想到了这一点。使用Arrays.toList(list).sublist(from,to).indexOf(o)
搜索[from, to)
范围内的元素。【参考方案2】:
数组没有indexOf()
方法。
也许这个 Apache Commons Lang ArrayUtils
方法就是你要找的
import org.apache.commons.lang3.ArrayUtils;
String[] colours = "Red", "Orange", "Yellow", "Green" ;
int indexOfYellow = ArrayUtils.indexOf(colours, "Yellow");
【讨论】:
Eclipse 找不到这个导入库。【参考方案3】:对于原语,如果你想避免装箱,Guava 有用于原语数组的助手,例如Ints.indexOf(int[] 数组,int 目标)
【讨论】:
其他解决方案都创建新的字符串或列表,或者只处理单个元素。 Guava 的 Chars.indexOf 可让您获取数组中数组的索引。这是正确的解决方案。【参考方案4】:没有。可以使用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()
从你的数组中创建一个
【讨论】:
使用T
具有误导性。它不提供任何类型安全,很容易误认为它是类型安全的……最好使用 Object
@VenkataRaju,在这里使用 T 会强制两个方法参数属于同一类型。这很有用。
@gonadarian 不是真的。这两个编译都很好:indexOf("str", new Object[] );
, indexOf(new Object(), new String[] );
@VenkataRaju 是的。您的示例并不能证明任何事情,因为 String 是一个 Object...所以显然 Object 数组可能包含一个您可能想要查找其索引的 String。
@ghert85 另一个例子:indexOf("str", new Date[] )
, indexOf(new Date(), new String[] )
【参考方案5】:
与 C# 中的 Array.IndexOf 方法和 javascript 中的 indexOf 方法不同,Java 的 API(尤其是 Array
和 Arrays
类)没有这样的方法。
这个方法 indexOf(连同它的补码 lastIndexOf)在java.util.List 接口中定义。注意 indexOf 和 lastIndexOf 没有重载,只接受一个 Object 作为参数。
如果您的数组已排序,那么您很幸运,因为 Arrays 类定义了 binarySearch 方法的一系列重载,这些重载将以可能的最佳性能找到您正在寻找的元素的索引( O(log n) 而不是 O(n),后者是您可以从 indexOf 完成的顺序搜索中所期望的。有四个考虑:
数组必须按照自然顺序或作为参数提供的比较器的顺序进行排序,或者至少所有“小于”键的元素必须在该元素之前数组和所有“大于”键的元素必须在数组中该元素之后;
通常使用 indexOf 进行的测试以确定键是否在数组中(验证返回值是否不是 -1)不适用于 binarySearch。您需要验证返回值是否不小于零,因为返回的值将指示键不存在,但如果它确实存在则预期的索引;
如果您的数组包含多个与键相等的元素,则从 binarySearch 获得的内容是未定义的;这与返回第一次出现的 indexOf 和返回最后一次出现的 lastIndexOf 不同。
如果布尔数组首先包含所有假然后所有真,则它可能看起来已排序,但这不算数。没有替代接受布尔数组的 binarySearch 方法,如果在检测第一个 true 出现在数组中的位置时,如果你想要 O(log n) 性能,你必须在那里做一些聪明的事情,例如使用数组布尔值和常量 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)的方法。在那里你可以找到indexOf 和lastIndexOf 的实现。
【讨论】:
【参考方案6】:Java ArrayList
有一个 indexOf
方法。 Java 数组没有这种方法。
【讨论】:
不仅仅是ArrayList
- 每个Java List
都有indexOf()
。【参考方案7】:
我不记得数组上有一个“indexOf”,除了为自己编写代码...尽管如果您的数组包含原始类型,您可能可以使用许多 java.util.Arrays#binarySearch(...)
方法之一(请参阅Arrays javadoc)
【讨论】:
【参考方案8】:List 接口有一个 indexOf() 方法,您可以使用 Array 的 asList() 方法从数组中获取一个 List。除此之外,Array 本身没有这样的方法。它确实有一个用于排序数组的 binarySearch() 方法。
【讨论】:
【参考方案9】:数组本身没有这种方法。然而,列表确实: indexOf
【讨论】:
不仅仅是ArrayList
- 每个Java List
都有indexOf()
。
是的,我刚刚指定了 ArrayList,因为这可能是最接近 OP 正在寻找的东西 :)【参考方案10】:
您可能想到的是java.util.ArrayList,而不是数组。
【讨论】:
【参考方案11】:java数组中没有直接的indexOf函数。
【讨论】:
【参考方案12】:Jeffrey Hantin 的回答很好,但它有一些限制,如果它这样做或那样做......
您可以编写自己的扩展方法,它总是按照您想要的方式工作。
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);
【讨论】:
【参考方案13】:int findIndex(int myElement, int[] someArray)
int index = 0;
for(int n: someArray)
if(myElement == n) return index;
else index++;
注意:这个方法可以用于 int 类型的数组,你也可以将该算法用于其他类型的小改动
【讨论】:
-1:首先这会改变我们可能不想要的要排序的原始数组。其次,它给出了排序数组的答案,而不是我们想要的原始数组(如果我们想要排序数组的答案,它已经被排序了)。第三,由于排序是 O(n log n),这比线性遍历数组要慢。所以这个答案既错误又低效。 使用就地排序时原始索引丢失。以上是关于Java 的数组 indexOf 在哪里?的主要内容,如果未能解决你的问题,请参考以下文章