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(尤其是 ArrayArrays 类)没有这样的方法。

这个方法 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 在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

Java 负数 indexOf (从末尾计数 [length()] )

数组的indexOf方法--数组去重

js判断数组中是否有重复元素

与字符串方法 .indexOf() Java 混淆的结果

JS确定元素在数组中的索引值

在java字符串中如何判断字符的类型