4

好的,所以这对我来说没有意义....也许有人可以阐明一下。我想出的将原始数组转换为 ArrayLists 的技术如下。

arr = new ArrayList<String>(Arrays.asList(primitveArray));

这很好用。但是今天,我开始想知道这是多么有效,因为我碰巧正在编写一些性能比以前更重要的代码。过去我曾在其他应用程序中工作过,并决定查看源代码Arrays.asList()

我找到了这个:

public static <T> List<T> asList(T... array) {
    return new ArrayList<T>(array);
}

我对自己说:“我真是个白痴,它只是将数组传递给 ArrayList 构造函数ArrayList<T>(T[] arr),我为什么不跳过一步而不使用愚蠢的 Arrays.asList 呢?

所以我试试这个

arr = new ArrayList<T>(primitveArray)

在我的代码中。但是突然之间ArrayList<T>(T[] arr)是不确定的。我很困惑为什么会这样?

4

6 回答 6

5

但是突然之间ArrayList<T>(T[] arr)是不确定的。我很困惑为什么会这样?

有两个类名为ArrayList

  • 一个是 的private static内部类java.util.Arrays
  • 另一个是java.util.ArrayList

asList()使用前者。您正在尝试使用后者。这两个类是不相关的,它们只是碰巧同名。

需要注意的是java.util.Arrays.ArrayList不复制数组。它提供了一个视图。

于 2012-05-25T17:01:24.317 回答
2

所以我试试这个arr = new ArrayList<T>(primitveArray)

T是一个泛型类型的参数,您不能在实例化 ArrayList 时使用它,只有在声明它在类或方法中使用时才能使用它。相反,将您的代码更改为:

arr = Arrays.asList(primitveArray);

Arrays 类中使用的 ArrayList 类与您在代码中使用的 ArrayList 类不同,它是 Arrays 类本身定义的内部类,并定义了一个以 Array 作为参数的构造函数。由于此类是私有的,具有非公共构造函数,因此只能在Arrays类本身内实例化和使用。

private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable
    {
        private static final long serialVersionUID = -2764017481108945198L;
    private final E[] a;

    ArrayList(E[] array) {
            if (array==null)
                throw new NullPointerException();
        a = array;
    }

...
于 2012-05-25T16:58:38.733 回答
2

好吧,在问了这个问题大约十秒钟后,我想通了。Apprentlyjava.util.Arrays实现了一个名为 ArrayList 的静态本地类,它与java.util.ArrayList. 令人困惑的是,它们都被命名为 ArrayList,但其中 asjava.util.Arrays.ArrayList被声明为

private static class ArrayList<E> extends AbstractList<E> implements
        List<E>, Serializable, RandomAccess

java.util.ArrayList被声明为

public class ArrayList<E> extends AbstractList<E> implements List<E>,
    Cloneable, Serializable, RandomAccess 

我想现在的问题是,为什么要这样做。我想可能是优化。由于 Array 将 ArrayList 转换为 List 它只需要支持足以执行 List 操作而无需其他ArrayList正常功能。

于 2012-05-25T17:03:21.073 回答
1

我想现在问题又来了,为什么会这样做

返回的列表是数组的视图,不会发生复制,并且对列表的任何更改在源数组中都是可见的。由于它始终由源数组支持,因此不支持任何影响列表大小的修改并引发异常。

于 2012-05-25T17:08:32.767 回答
1

你要意识到的最重要的事情是它Arrays.asList完全高性能的,它是 O(1),固定开销非常小。这是因为没有数据被复制。它只是为您的数组提供了一个List与之交互的接口。其次,这private static class ArrayList确实非常重要,因为它public class ArrayList 确实会复制数据并导致性能下降。

于 2012-05-25T17:09:35.833 回答
1

我想现在的问题是,为什么要这样做。

(an )List返回的。是原始数组的视图。如果你改变它,数组就会改变,如果你改变数组,它就会改变。如果您尝试执行任何调整大小的操作,则会引发异常,因为您无法调整原始数组的大小。Arrays.asListArrays.ArrayList

它只是一个适配器,可以有效地将原始数组视为 aList而无需将元素复制到List.

当你这样做

new java.util.ArrayList( Arrays.asList( primitiveArray ) );

是当您复制元素时。结果不是视图,而是独立于原始数组。而且,您还获得了调整大小的能力。如果您查看源代码(您必须同时查看java.util.ArrayListand Arrays.ArrayList,您会发现它以最有效的方式将这些元素从原始原始数组复制到支持 的数组中java.util.ArrayList,因此不会丢失效率要担心。

于 2012-05-25T17:22:23.260 回答