数组列表初始化等价于数组初始化

我知道你可以在实例化过程中初始化一个数组,如下:

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

有没有办法对数组列表做同样的事情?或者我必须用array.add()单独添加内容?

230682 次浏览

在Java中,列表没有文字语法,所以你必须使用.add()。

如果你有很多元素,这有点啰嗦,但你可以:

  1. 使用Groovy或类似的东西
  2. 使用arrays . aslist(数组)

2看起来像这样:

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

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

是的。

new ArrayList<String>()\{\{
add("A");
add("B");
}}

这实际上是在创建一个从ArrayList<String>派生的类(外部花括号集做这件事),然后声明一个静态初始化器(内部花括号集)。这实际上是包含类的内心的类,因此它将有一个隐式this指针。这不是问题,除非你想序列化它,或者你希望外部类被垃圾收集。

我理解Java 7将提供其他语言结构来做你想做的事情。

编辑:最近的Java版本为创建这样的集合提供了更多可用的函数,并且值得研究以上(在这些版本之前提供)

arrays . aslist可以在这里提供帮助:

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

这是你能得到的最接近的答案:

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

你可以用更简单的方法:

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

查看数组的源代码。asList,它构造一个数组列表,但默认情况下转换为List。所以你可以这样做(但对新的jdk不可靠):

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

这是如何使用op4j Java库的流畅接口来完成的。12月10日发布):-

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

这是一个非常酷的库,可以节省你大量的时间。

这个怎么样?

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

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

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

让我们先来了解一下发生了什么:

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

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

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

    public ArrayList(Collection<? extends E> collection) {
    ......
    Object[] a = collection.toArray();
    }
    
  3. Next the constructor decides whether to adopt the cloned array, or copy it again to remove the subclass type. Since Arrays.asList(T...) internally uses an array of type T, the very same one we passed as the parameter, the constructor always rejects using the clone unless T is a pure Object. (E.g. String, Integer, etc all get copied again, because they extend Object).

    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;
    

Thus, our data was copied 3x just to explicitly initialize the ArrayList. We could get it down to 2x if we force Arrays.AsList(T...) to construct an Object[] array, so that ArrayList can later adopt it, which can be done as follows:

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

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