我们无法对从Arrays.asList
获取的集合执行<Collection>.add
或者<Collection>.addAll
操作,只有删除操作是允许的。
那么如果我遇到这样一个场景:我需要在List
中添加新元素而不删除先前的元素。我该如何实现?
使用构造函数创建一个新的ArrayList
:
List<String> list = new ArrayList<String>(Arrays.asList("a", "b"));
一种方法是构造一个新的 ArrayList
:
List<T> list = new ArrayList<T>(Arrays.asList(...));
在完成这一步之后,您可以随心所欲地修改list
。
Arrays.asList()方法会生成一个列表,实际上它是由数组支持的,这个数组被转换成了列表。虽然你可以把它当作列表使用,但是你不能执行一些操作,例如添加新元素。所以最好的选择是将它传递给另一个列表对象的构造函数,像这样:
List<T> list = new ArrayList<T>(Arrays.asList(...));
您可以使用Java8流绕过中间的ArrayList
:
Integer[] array = {1, 2, 3};
List<Integer> list = Streams.concat(Arrays.stream(array),
Stream.of(4)).collect(Collectors.toList());
这应该相当高效,因为它只需遍历数组并预先分配目标列表。对于大型数组可能更好,也可能不是。像往常一样,如果这很重要,你需要进行测量。
在下面的示例中,Collection(例如ArrayList)的构造函数将以数组形式作为列表,并使用该列表的元素构造新实例。
List<T> list = new ArrayList<T>(Arrays.asList(...));
http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList(java.util.Collection)
现在,使用流API可以以简洁和功能强大的方式轻松获取 ArrayList
:
Stream.of("str1", "str2").collect(Collectors.toList()));
当然,这也有灵活性可以使用映射进行转换。例如,在编写Spring安全代码的单元测试时,编写以下内容非常方便:
Stream.of("ROLE_1", "ROLE_2").map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
Collectors.toList
返回的列表是一个 ArrayList
,可以通过您的代码根据需要进行修改。Arrays.asList()
创建对象时生成一个不可修改的列表。您可以使用以下代码。
List list = Collections.synchronizedList(new ArrayList(...));
这个转换器允许列表添加和删除对象。我只在Java 8中进行了测试。
ArrayList<Object> MyObjectList = new ArrayList<>();
Arrays.asList(params[1]).forEach((item)-> {
MyObjectList.add(item);
});
asList
返回一个新的ArrayList
。哦,这不是同一个ArrayList
。 - Sotirios Delimanolisjava.util.Arrays.ArrayList
。 - Sotirios Delimanolisjava.util.Arrays.ArrayList
,只是保证你会得到一个固定大小的List
(所以当试图改变其大小时,抛出UnsupportedOperationException
是有道理的)。然而,java.util.ArrayList
(不是java.util.Arrays$ArrayList
)是“List接口的可调整大小的数组实现”,根据文档。 - Joshua Taylor