【问题标题】:Where is Java's Array indexOf?Java 的数组 indexOf 在哪里?
【发布时间】:2011-06-25 03:27:29
【问题描述】:

我一定是遗漏了一些很明显的东西,但是我已经搜索了一遍,找不到这个方法。

【问题讨论】:

    标签: java arrays indexof


    【解决方案1】:

    有几种方法可以使用Arrays 实用程序类来完成此操作。

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

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

    如果数组 原语且未排序,则应使用其他答案之一提供的解决方案,例如 Kerem Baydoğan'sAndrew McKinlay'sMishax'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 完成的顺序搜索中所期望的。有四个考虑:

    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 方法相比,这肯定会具有性能优势。如果您担心编写遍历数组所有元素的强力 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 的实现。

    【讨论】:

      【解决方案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),这比线性遍历数组要慢。所以这个答案既错误又低效。
                • 使用就地排序时原始索引丢失。
                猜你喜欢
                • 1970-01-01
                • 2012-06-19
                • 1970-01-01
                • 2012-03-15
                • 2018-04-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-11-17
                相关资源
                最近更新 更多