• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

Java中一行代码初始化集合的多种方式

技术杂谈 勤劳的小蚂蚁 3个月前 (02-13) 86次浏览 已收录 0个评论 扫描二维码

1. 简介

在这个快速教程中,我们将研究如何使用一行代码初始化集合。

2. 利用数组创建

我们可以用一个数组创建集合,我们可以用数组工具类在一行程序中初始化它们:
  1.    List<String> list =Arrays.asList(newString[]{"foo","bar"});
我们能信任变量参数机制来处理数组的创建。这样,我们可以写出更简洁、更易读的代码:
  1. @Test
  2. publicvoid givenArrayAsList_thenInitialiseList(){
  3.    List<String> list =Arrays.asList("foo","bar");
  4.    assertTrue(list.contains("foo"));
  5. }
该代码的运行结果是实现了集合的接口,但是它既不是java.util.ArrayList也不是LinkedList。相反,它是一个由原始数组支持的集合,该数组有两个含义。
尽管类的名称也叫ArrayList,但是它却在java.util.Arrays包中。

2.1. 固定的长度

利用Arrays.asList创建的集合有固定的长度。
  1. @Test(expected =UnsupportedOperationException.class)
  2. publicvoid givenArraysAsList_whenAdd_thenUnsupportedException(){
  3.    List<String> list =Arrays.asList("foo","bar");
  4.    list.add("baz");
  5. }

2.2. 共享的引用

原始的数组和集合共享着对象的引用:
  1. @Test
  2. publicvoid givenArraysAsList_whenCreated_thenShareReference(){
  3.    String[] array ={"foo","bar"};
  4.    List<String> list =Arrays.asList(array);
  5.    array[0]="baz";
  6.    assertEquals("baz", list.get(0));
  7. }

3. 利用流创建 (Java 8)

我们能很容易地将流转换为任何类型的集合。
因此,使用流的工厂方法,我们可以在一行程序中创建和初始化集合
  1. @Test
  2. publicvoid givenStream_thenInitializeList(){
  3.    List<String> list =Stream.of("foo","bar")
  4.      .collect(Collectors.toList());
  5.    assertTrue(list.contains("foo"));
  6. }
在这里,我们应该注意Collectors.toList()并不能保证返回的集合是准确的。
对于返回的实例的可变性、可序列化性或线程安全性,一般没有约定。因此,我们的代码不应该依赖于这些属性。
一些人强调说,Stream.of(…).collect(…) 可能比Arrays.asList() 具有更大的内存和性能占用空间,但是在几乎所有情况下,它都是一个非常微小的优化,几乎没有什么区别。

4. 工厂方法 (Java 9)

在JDK 9中,为集合引入了几种简便的工厂方法:
  1. List<String> list =List.of("foo","bar","baz");
  2. Set<String>set=Set.of("foo","bar","baz");
一个重要的细节是返回的实例是不可变的。此外,工厂方法在空间效率和线程安全方面有几个优势。
本文将进一步探讨这个主题。

5. 双括号初始化

在某些地方,我们发现一种名为“双括号初始化”的方法,它看起来如下:
  1. @Test
  2. publicvoid givenAnonymousInnerClass_thenInitialiseList(){
  3.    List<String> cities =newArrayList(){{
  4.        add("New York");
  5.        add("Rio");
  6.        add("Tokyo");
  7.    }};
  8.    assertTrue(cities.contains("New York"));
  9. }
“双括号初始化”的名称很容易误导人。语法看起来紧凑而优雅,但它危险地隐藏了底层的内容。
实际上在Java中并没有“双括号”语法,它们是故意这样格式化的两个代码块。
使用外部大括号,我们声明一个匿名的内部类,它将是ArrayList的子类。在这些大括号中,我们可以声明子类的细节。
通常,我们可以使用实例初始化代码块,这也就是内部大括号的来源。
这种语法的简洁很吸引人,但它被认为是反模式的。
要阅读有关双括号初始化的更多信息,请参阅本文。

6. 结论

现代Java提供了几种在一行程序中创建集合的选择。 我们完全可以依据个人喜好选择的方法,而不是技术推理。
一个重要的要点是,尽管匿名内部类初始化的反模式(又名“双括号”)看起来很优雅,但它有很多负面的副作用。

丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:Java中一行代码初始化集合的多种方式
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00