关于java:ArrayList初始化等效于数组初始化

ArrayList initialization equivalent to array initialization

本问题已经有最佳答案,请猛点这里访问。

我知道您可以在实例化期间初始化数组,如下所示:

1
String[] names = new String[] {"Ryan","Julie","Bob"};

有没有办法用数组列表做同样的事情?还是必须用EDOCX1[0]单独添加内容?


arrays.aslist可以在以下方面提供帮助:

1
new ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21));


对。

1
2
3
4
new ArrayList<String>(){{
   add("A");
   add("B");
}}

这实际上是在创建一个从ArrayList派生的类(大括号的外部集执行此操作),然后声明一个静态初始化器(大括号的内部集)。这实际上是包含类的一个内部类,因此它将有一个隐式的this指针。这不是问题,除非您希望序列化它,或者您希望外部类被垃圾收集。

我理解Java 7将提供额外的语言构造来精确地做您想要的。

编辑:最近的Java版本为创建这样的集合提供了更多可用的功能,并且值得在上面进行调查(在这些版本之前提供的时间)


这里是你能得到的最接近的:

1
ArrayList<String> list = new ArrayList(Arrays.asList("Ryan","Julie","Bob"));

您可以更简单地使用:

1
List<String> list = Arrays.asList("Ryan","Julie","Bob")

查看arrays.aslist的源代码,它构造一个arraylist,但默认情况下是强制转换为list。所以您可以这样做(但对于新的JDK不可靠):

1
ArrayList<String> list = (ArrayList<String>)Arrays.asList("Ryan","Julie","Bob")


1
Arrays.asList("Ryan","Julie","Bob");

在Java中,没有列表的文字语法,所以必须这样做。

如果你有很多元素,这有点冗长,但是你可以:

  • 使用groovy或类似的东西
  • 使用array.aslist(array)
  • 2看起来像:

    1
    2
    String[] elements = new String[] {"Ryan","Julie","Bob"};
    List list = new ArrayList(Arrays.asList(elements));

    但这会导致一些不必要的对象创建。


    选择的答案是:ArrayList(Arrays.asList(1,2,3,5,8,13,21));

    但是,在创建最终数组之前,了解所选答案在内部多次复制元素是很重要的,并且有一种方法可以减少某些冗余。

    让我们从了解正在发生的事情开始:

  • 首先,元素被复制到静态工厂Arrays.asList(T...)创建的Arrays.ArrayList中。

    尽管具有相同的简单类名,但这不会产生与java.lang.ArrayList相同的类。它不实现像remove(int)这样的方法,尽管它有一个列表接口。如果调用这些方法,它将抛出一个UnspportedMethodException。但是如果你只需要一个固定大小的列表,你可以停在这里。

  • 接下来,在1中构造的Arrays.ArrayList被传递给构造函数ArrayList<>(Collection),在这里调用collection.toArray()方法来克隆它。

    1
    2
    3
    4
    public ArrayList(Collection<? extends E> collection) {
    ......
    Object[] a = collection.toArray();
    }
  • 接下来,构造函数决定是采用克隆的数组,还是再次复制它以删除子类类型。由于Arrays.asList(T...)在内部使用类型为t的数组(与我们作为参数传递的数组相同),因此构造函数总是拒绝使用克隆,除非t是纯对象。(例如,字符串、整数等都会再次被复制,因为它们会扩展对象)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    if (a.getClass() != Object[].class) {      
        //Arrays.asList(T...) is always true here
        //when T subclasses object
        Object[] newArray = new Object[a.length];
        System.arraycopy(a, 0, newArray, 0, a.length);
        a = newArray;
    }
    array = a;
    size = a.length;
  • 因此,我们的数据被复制了3x,只是为了显式地初始化arraylist。如果强制Arrays.asList(T...)构造一个object[]数组,我们可以把它降到2X,这样arraylist以后可以采用它,具体操作如下:

    1
    (List<Integer>)(List<?>) new ArrayList<>(Arrays.asList((Object) 1, 2 ,3, 4, 5));

    或者只是在创建之后添加元素可能仍然是最有效的。


    这个怎么样。

    1
    2
    ArrayList<String> names = new ArrayList<String>();
    Collections.addAll(names,"Ryan","Julie","Bob");

    这就是如何使用OP4J Java库的FLUENT接口完成的(1.1)。10年12月发布):。-

    1
    List<String> names = Op.onListFor("Ryan","Julie","Bob").get();

    这是一个非常酷的图书馆,可以节省你一吨时间。