【问题标题】:Index of an element in an array using Java使用 Java 对数组中的元素进行索引
【发布时间】:2015-10-22 13:05:30
【问题描述】:

Java 中的以下代码返回 -1。我认为它应该返回 3。

int[] array = {1,2,3,4,5,6}; 
System.out.println(Arrays.asList(array).indexOf(4));

你能帮我理解一下这个函数是如何工作的吗?

谢谢

【问题讨论】:

  • Arrays.asList 不适用于原始数组。它给出了一个包含原始int[]List<int[]>。 -1 表示 4 不是 List 项之一
  • Arrays.asList(int[]) 正在创建一个包含整个 int[] 数组的元素的 List。将int[]改为Integer[]
  • 尝试显式地编写asList 的泛型类型(Arrays.<int>asList(array))而不是依赖类型推断,编译器会告诉你为什么这样行不通。
  • Guava's Ints.asList() 解决了这个问题; more info.

标签: java arrays


【解决方案1】:

在 Java 5 之前,Arrays.asList 用于接受 Object[]。当泛型和可变参数被引入到语言中时,它被更改为

public static <T> List<T> asList(T... arr)

在您的示例中,T 不能是 int,因为 int 是原始类型。不幸的是,签名与 T 匹配,而不是等于 int[],这是一个引用类型。结果是你最终得到一个包含数组的List,而不是整数的List

在 Java 4 中,您的代码不会编译,因为 int[] 不是 Object[]。不编译比产生奇怪的结果更可取,在 Effective Java 中,Josh Bloch 说将 asList 改造为可变参数方法是一个错误。

【讨论】:

    【解决方案2】:

    Arrays.asList 期望一个对象(或更多)。您的数组 (array) 是唯一的对象,因此调用该方法将创建一个仅包含一个对象的列表,即您的数组。

    在您的列表中调用 indexOf 将返回 -1,因为永远不会找到 4,因为您的列表包含数组对象,而不是您的数组包含的数据列表。

    【讨论】:

      【解决方案3】:
      int[] array = {1,2,3,4,5,6};
      Arrays.stream(array).boxed().collect(Collectors.toList()).indexOf(4);
      

      应该做你想做的,同时保留原来的int[]

      你得到一个IntStream,把它装进Stream&lt;Integer&gt;,收集到List&lt;Integer&gt;,然后可以进行.indexOf()搜索。

      【讨论】:

      • 您可能希望使用IntStream 而不是将所有数组存储到一个列表中以调用indexOf - OptionalInt index = IntStream.range(0, array.length).filter(i -&gt; array[i] == 4).findFirst();
      【解决方案4】:

      当您使用Arrays.asList() 时,您已经得到了有关您的阵列发生了什么的答案。

      其他需要考虑的事项:

      • 由于您的数组已排序,请考虑Arrays.binarySearch()
      • 如果您的数组未排序,一个简单的自定义 indexOf 方法可以执行相同的操作,而不会浪费将 int[] 转换为 List&lt;Integer&gt; 的周期

      例子:

      public static void main(String[] args) throws Exception {
          int[] array = {1, 2, 3, 4, 5, 6};
          System.out.print("Binary Search: ");
          System.out.println(Arrays.binarySearch(array, 4));
      
          int[] array2 = {5, 8, 2, 5, 3, 4, 1};
          System.out.print("Manual Search: ");
          System.out.println(indexOf(array2, 4));
      }
      
      public static int indexOf(int[] array, int search) {
          for (int i = 0; i < array.length; i++) {
              if (array[i] == search) {
                  return i;
              }
          }
          return -1;
      }
      

      结果:

      Binary Search: 3
      Manual Search: 5
      

      【讨论】:

        【解决方案5】:

        由于您使用的是原始类型的数组,因此这将不起作用。该数组的类型为 int。例如,您是否使用Integer 类型,这将起作用。 -1 表示未找到指定元素的索引。

        这就是你想要做的:

        Integer[] array = {1,2,3,4,5,6};
        System.out.println(Arrays.asList(array).indexOf(4));
        

        【讨论】:

          【解决方案6】:

          在 Java 中你不能使用 int 等原始类型作为泛型类的参数,因为 int 不是类,你应该使用 Integer 来代替:

          Integer[] array = {1,2,3,3,4,5}; 
          
          List Arraylist=Arrays.asList(array);
          System.out.println(Arraylist.indexOf(1));
          System.out.println(Arraylist.indexOf(4));
          

          输出:

          0
          4
          

          注意Arraylist.indexOf(i)返回列表中元素i第一次出现的索引:

          System.out.println(Arraylist.indexOf(3));
          

          它将返回 2 ,这是元素 3 的第一次出现,而不是 3 因为列表中有 3 的 2 个元素。

          【讨论】:

            【解决方案7】:

            因为当您对主数据类型数组执行此操作时,它将被视为列表中的第一个元素。

            int[] array = {1,2,3,4,5,6};
            System.out.println(Arrays.asList(array));
            

            你会得到这个:

            [[I@474e8d67]
            

            【讨论】:

              【解决方案8】:
              int[] array = {1,2,3,4,5,6};
              
              • 在java中array被认为是Object
              • int[] 特别是 Object 而不是 Object[]
              • 要调用Arrays.asList,您需要零个或多个Objects

              您的方法以这种方式被调用,

              Arrays.asList((Object)(array));//Yes
              Arrays.asList(1,2,3,4,5,6);//No
              

              所以你将拥有List&lt;int[]&gt; 而不是List&lt;Integer&gt;

              现在,您可能会问自己,如果Arrays.asList(1,2,3,4)Arrays.asList(arrayInt) 更有效?

              Arrays.asList(1,2,3,4) 中,所有值都自动装箱Integer 中,Object 因此在上述情况下Integer[] cad 可以解决问题。

              【讨论】:

                猜你喜欢
                • 2015-12-03
                • 2020-08-07
                • 2023-01-31
                • 1970-01-01
                • 2020-07-03
                • 2019-05-17
                • 1970-01-01
                • 1970-01-01
                • 2017-11-02
                相关资源
                最近更新 更多