Initialization of an ArrayList in one line
我想创建一个用于测试的选项列表。起初,我这样做:
1 2 3 4 | ArrayList<String> places = new ArrayList<String>(); places.add("Buenos Aires"); places.add("Córdoba"); places.add("La Plata"); |
然后我重构代码如下:
1 2 | ArrayList<String> places = new ArrayList<String>( Arrays.asList("Buenos Aires","Córdoba","La Plata")); |
有更好的方法吗?
如果你只是把它声明为一个
1 |
或者如果只有一个元素:
1 |
这意味着
要创建一个具体的
1 |
实际上,初始化
1 2 3 4 | ArrayList<String> list = new ArrayList<String>(); list.add("A"); list.add("B"); list.add("C"); |
关键是,要引用该
有一些替代方法,例如使用实例初始值设定项生成匿名内部类(也称为"双括号初始化"):
1 2 3 4 5 | ArrayList<String> list = new ArrayList<String>() {{ add("A"); add("B"); add("C"); }}; |
但是,我不太喜欢这个方法,因为您最终得到的是一个
如果项目硬币的集合文字建议被接受(它是在Java 7中引入的,但是它也不太可能是Java 8的一部分),那就好了。
1 | List<String> list = ["A","B","C"]; |
不幸的是,它在这里对您没有帮助,因为它将初始化一个不可变的
简单的答案
在Java 10或更高版本中:
1 |
在Java 9或更高版本中:
1 |
这将给您一个不变的
1 |
这将给您一个由数组支持的
通过静态导入,可以使
1 | List<String> strings = asList("foo","bar","baz"); |
静态导入:
1 |
任何现代的IDE都会建议并自动为您做这些。例如,在intellij idea中,您按
但是,我不建议缩短Java 9 EDCOX1 6的方法,因为只有EDCX1 7的内容变得混乱。
为什么必须是一个
1 | Stream<String> strings = Stream.of("foo","bar","baz"); |
您可以连接
1 2 | Stream<String> strings = Stream.concat(Stream.of("foo","bar"), Stream.of("baz","qux")); |
或者你可以从一个
1 2 3 | import static java.util.stream.Collectors.toList; List<String> strings = Stream.of("foo","bar","baz").collect(toList()); |
但最好使用
(你可能没有。)引用jep 269(强调我的):
There is a small set of use cases for initializing a mutable collection instance with a predefined set of values. It's usually preferable to have those predefined values be in an immutable collection, and then to initialize the mutable collection via a copy constructor.
如果你想预先填充一个
1 2 |
或在Java 8或更早:
1 2 | ArrayList<String> strings = new ArrayList<>(asList("foo","bar")); strings.add("baz"); |
或使用
1 2 3 4 5 | import static java.util.stream.Collectors.toCollection; ArrayList<String> strings = Stream.of("foo","bar") .collect(toCollection(ArrayList::new)); strings.add("baz"); |
但同样,最好是直接使用
你说你已经在代码中声明了这个列表为
你很可能不会这么做。
通常,您只需通过要使用的最通用的接口(如
否则,您将把代码限制为特定的类型,并且在需要时更难更改。
例如,如果您将一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // Iterable if you just need iteration, for (String s : strings): void method(Iterable<String> strings) { for (String s : strings) { ... } } // Collection if you also need .size(), .isEmpty(), or .stream(): void method(Collection<String> strings) { if (!strings.isEmpty()) { strings.stream()... } } // List if you also need .get(index): void method(List<String> strings) { strings.get(...) } // Don't declare a specific list implementation // unless you're sure you need it: void method(ArrayList<String> strings) { ??? // You don't want to limit yourself to just ArrayList } |
另一个例子是声明变量
如果您需要1号的简单列表:
1 |
如果需要多个对象的列表:
1 2 |
有了番石榴,你可以写:
1 | ArrayList<String> places = Lists.newArrayList("Buenos Aires","Córdoba","La Plata"); |
在guava中还有其他有用的静态构造函数。你可以在这里读到它们。
集合文字没有使它成为Java 8,但是可以使用流API在一个相当长的行中初始化列表:
1 | List<String> places = Stream.of("Buenos Aires","Córdoba","La Plata").collect(Collectors.toList()); |
如果您需要确保您的
1 | ArrayList<String> places = Stream.of("Buenos Aires","Córdoba","La Plata").collect(Collectors.toCollection(ArrayList::new)); |
1 2 3 4 5 | import com.google.common.collect.ImmutableList; .... List<String> places = ImmutableList.of("Buenos Aires","Córdoba","La Plata"); |
如JDK增强方案-269中建议的那样,使用
同样,类似的方法也适用于
这类似于@coobird提出的收集文字建议。在jep文件中进一步澄清-
选择
Language changes have been considered several times, and rejected:
Project Coin Proposal, 29 March 2009
Project Coin Proposal, 30 March 2009
JEP 186 discussion on lambda-dev, January-March 2014
The language
proposals were set aside in preference to a library-based proposal as
summarized in this message.
Java9中过载的便利工厂方法的要点是什么?
可以创建工厂方法:
1 2 3 4 5 6 7 8 9 10 11 12 |
但这并不比第一次重构好多少。
为了获得更大的灵活性,它可以是通用的:
1 2 3 4 5 6 7 | public static <T> ArrayList<T> createArrayList(T ... elements) { ArrayList<T> list = new ArrayList<T>(); for (T element : elements) { list.add(element); } return list; } |
在Java 9中,我们可以很容易地在一行中初始化EDCOX1×3条:
1 |
或
1 |
Java 9的这种新方法比以前的有很多优点:
请参阅本文了解更多详细信息->list.of和arrays.aslist之间的区别是什么?
另一种方法是:
1 | List<String> values = Stream.of("One","Two").collect(Collectors.toList()); |
只需使用下面的代码,如下所示。
1 2 3 4 5 | List<String> list = new ArrayList<String>() {{ add("A"); add("B"); add("C"); }}; |
使用Eclipse集合(以前称为GS集合),可以编写以下内容:
1 | List<String> list = Lists.mutable.with("Buenos Aires","Córdoba","La Plata"); |
您还可以更具体地了解类型以及它们是可变的还是不可变的。
1 2 | MutableList<String> mList = Lists.mutable.with("Buenos Aires","Córdoba","La Plata"); ImmutableList<String> iList = Lists.immutable.with("Buenos Aires","Córdoba","La Plata"); |
您也可以对套装和行李进行同样的操作:
1 2 3 4 5 6 7 | Set<String> set = Sets.mutable.with("Buenos Aires","Córdoba","La Plata"); MutableSet<String> mSet = Sets.mutable.with("Buenos Aires","Córdoba","La Plata"); ImmutableSet<String> iSet = Sets.immutable.with("Buenos Aires","Córdoba","La Plata"); Bag<String> bag = Bags.mutable.with("Buenos Aires","Córdoba","La Plata"); MutableBag<String> mBag = Bags.mutable.with("Buenos Aires","Córdoba","La Plata"); ImmutableBag<String> iBag = Bags.immutable.with("Buenos Aires","Córdoba","La Plata"); |
注意:我是Eclipse集合的提交者。
最紧凑的方法是:
您可以使用以下语句:
代码片段:(应该是评论,但是太长了,所以新回复)。正如其他人提到的,
1 2 3 4 5 6 |
由于
1 |
这可能是实现这一点的最佳方法,特别是如果您需要一个无边界的列表或需要使用继承。
Java 9具有以下方法来创建一个不可变列表:
1 |
如果需要,它很容易适应创建可变列表:
1 |
类似的方法也适用于
就像汤姆所说:
1 |
但是,由于您抱怨需要ArrayList,您首先应该知道ArrayList是List的一个子类,您可以简单地添加这一行:
1 |
不过,这可能会让你抱怨"表现"。
在这种情况下,它对我没有意义,为什么,因为您的列表是预先定义的,所以它没有被定义为数组(因为初始化时大小是已知的)。如果这是你的选择:
1 |
如果您不关心细微的性能差异,那么您也可以非常简单地将数组复制到arraylist:
好吧,但是将来你需要的不仅仅是地名,你还需要一个国家代码。假设这仍然是一个预先定义的列表,在运行时永远不会更改,那么使用
1 | enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA} |
将成为:
1 2 3 4 5 6 7 8 9 10 11 12 |
枚举有一个静态
1 2 3 4 |
那样的话,我想你不需要你的阵列列表。
P.S.Randya演示了另一种使用静态实用工具方法collections.addall的好方法。
1 |
您可以使用cactoos的
1 2 3 | List<String> names = new StickyList<>( "Scott Fitzgerald","Fyodor Dostoyevsky" ); |
尝试使用此代码行:
1 |
是的,在数组的帮助下,您可以在一行中初始化数组列表,
1 |
在爪哇,你做不到
1 | ArrayList<String> places = new ArrayList<String>( Arrays.asList("Buenos Aires","Córdoba","La Plata")); |
如前所述,您需要执行双括号初始化:
1 | List<String> places = new ArrayList<String>() {{ add("x"); add("y"); }}; |
但这可能会迫使您添加注释
或者你也可以
但是你可能想做一个
根据JavaDoc,您应该能够做到:
1 |
但是我不能用JDK1.6编译它。
1 |
如果你需要一个物品清单!
集合来自java.util包。
最好的方法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package main_package; import java.util.ArrayList; public class Stackkkk { public static void main(String[] args) { ArrayList<Object> list = new ArrayList<Object>(); add(list,"1","2","3","4","5","6"); System.out.println("I added" + list.size() +" element in one line"); } public static void add(ArrayList<Object> list,Object...objects){ for(Object object:objects) list.add(object); } } |
只需创建一个可以拥有任意多个元素的函数,并调用它将它们添加到一行中。
这是AbacusUtil的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // ArrayList List<String> list = N.asList("Buenos Aires","Córdoba","La Plata"); // HashSet Set<String> set = N.asSet("Buenos Aires","Córdoba","La Plata"); // HashMap Map<String, Integer> map = N.asMap("Buenos Aires", 1,"Córdoba", 2,"La Plata", 3); // Or for Immutable List/Set/Map ImmutableList.of("Buenos Aires","Córdoba","La Plata"); ImmutableSet.of("Buenos Aires","Córdoba","La Plata"); ImmutableSet.of("Buenos Aires", 1,"Córdoba", 2,"La Plata", 3); // The most efficient way, which is similar with Arrays.asList(...) in JDK. // but returns a flexible-size list backed by the specified array. List<String> set = Array.asList("Buenos Aires","Córdoba","La Plata"); |
声明:我是AbacusUtil的开发者。
为什么不做一个简单的实用函数来实现这一点呢?
1 2 3 4 5 |
"EDOCX1"〔0〕代表"字面清单"。
1 | ArrayList<String> places = ll("Buenos Aires","Córdoba","La Plata"); |
对于我来说,array.aslist()是最好和方便的。我总是喜欢这样初始化。如果您是Java集合的初学者,那么我希望您参考ARARYLIST初始化。
实际上,可以用一行来完成:
1 |
1 2 3 | public static <T> List<T> asList(T... a) { return new ArrayList<T>(a); } |
这是
1 |