Java9特性--集合API变化

313 阅读4分钟

在本教程中,我们将通过实例来了解Java9的特点--集合API的改进。

Java9集合API的改进

Java9对java.util.Listjava.util.Map、_java.util.Se_t接口增加了一些小的API变化。

增加了新的静态工厂方法 - of(collection),并按迭代顺序返回未修改的集合 - List、Set 和 Map。

该方法接受一列参数作为输入,并分别返回List、Set和Map的未修改集合。

更多信息请参见JEP 269集合的方便工厂方法。

为什么引入集合的工厂方法?

在java9版本之前,我们有很多方法可以为一些数据项创建一个未修改的集合

下面的部分包含了各种创建未修改的集合的方法和例子。在这个例子中,以列表为例,我们可以用同样的过程来声明和定义Set和Map。

创建简单的未修改的集合

我们将创建一个未修改的列表,Set或Map的元素很少,这是很繁琐的工作,而且会创建不必要的对象,首先你需要创建一个列表,接下来构造对象/元素,将它们分配给局部变量,通过多次调用add(如果是列表)方法来添加这个元素,如果是Set和Map,则将普通列表转换为未修改的列表。

List list = new ArrayList<>();    
list.add("one");              
list.add("two");  
list = Collections.unmodifiableList(list);  

复制构造器 未修改的集合创建

这是另一种创建glist的方法,使用Arrays.asList方法定义字符串数组,通过ArrayList构造函数来填充。

List stringList = Collections.unmodifiableList(  
new ArrayList<>(Arrays.asList("one", "two")));

Double Brace 未修改的集合创建

在这个例子中,使用匿名的内部类,在双括号中创建实例。

List strList = Collections.unmodifiableList(new ArrayList<>() {{  
add("one"); add("two"); add("three");  
}});  

Java8未修改的集合创建

使用Stream.of()方法将字符串阵列转换为Stream,使用Collectors.toList()方法将蒸汽转换为List。

List strLists = Collections.unmodifiableList(  
Stream.of("one", "two", "three").collect(Collectors.toList()));  

在java9中,我们可以简单地创建未经修改的集合。我们将在下面的例子中看到。

List和Set的语法和签名

List和Set都有重载的of()方法,参数为0到10。List和Set的语法和签名是一样的。

static  List of()  
static  List of(E e1)  
static  List of(E e1,E e2)  
// ..... so on upto ten parameters  
static  List of(E... e) // variable arguments  
static  Set of()  
static  Set of(E e1)  
static  Set of(E e1,E e2)  
// ..... so on upto ten parameters  
static  Set of(E... e) // variable arguments  

地图 语法和签名

map也有0到10个参数的静态方法。

static  Map of(K k1, V v1, K k2, V v2, K k3, V v3) 

像List和Set一样,Map也有一个变量参数方法的版本

static  Map ofEntries(Map.Entry... entries)

List.of()工厂静态方法示例

创建一个列表很简单,代码也很短。它需要三个元素作为输入并返回大小为3的列表。由于这个方法被重载了10个参数,你最多可以提供10个元素。如果需要插入更多的元素,你可以使用一个方法的可变参数版本。

List strList = List.of("one", "two", "three","four");

Set.of() 工厂静态方法示例

Set.of方法接受三个参数作为输入并返回一个未修改的集合。

Set stringSet = Set.of("set1", "set2", "set3");  

这个方法of()不允许重复的元素,重复的元素会抛出java.lang.IllegalArgumentException:重复的元素。

Set.of("one", "two", "three", "one");  

上述代码的输出是

 Exception in thread "main" java.lang.IllegalArgumentException: duplicate element: one  
 at java.base/java.util.ImmutableCollections$SetN.(ImmutableCollections.java:463)  
 at java.base/java.util.Set.of(Set.java:521)  
 at org.cloudhadoop.datetime.LamdaExpressionThisExample.main(LamdaExpressionThisExample.java:41)

Map.of() 工厂静态方法示例

这个接口有两个方法of和ofEntries用于创建集合。

版本一用于创建地图了

Map mapDemo = Map.of(1, "one", 2, "two", 3, "three");  
 // variable arguments example  
Map map = Map.ofEntries(  
  new AbstractMap.SimpleEntry<>("key1", "value1"),  
  new AbstractMap.SimpleEntry<>("key2", "value2"),  
  new AbstractMap.SimpleEntry<>("key3", "value3"));  

重复的键

用of()向Map传递重复的键,抛出java.lang.IllegalArgumentException:重复的键异常

Map.of("one", "value1", "one", "value2");  

而输出是

Exception in thread "main" java.lang.IllegalArgumentException: duplicate key: one  
at java.base/java.util.ImmutableCollections$MapN.(ImmutableCollections.java:681)  
at java.base/java.util.Map.of(Map.java:1327)  
at org.cloudhadoop.datetime.LamdaExpressionThisExample.main(LamdaExpressionThisExample.java:41)  

未修改的集合 - java.lang.UnsupportedOperationException 异常

Set strSet = Set.of("one", "two");  
strSet.add("three");  

输出是

Exception in thread "main" java.lang.UnsupportedOperationException  
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:71)  
at java.base/java.util.ImmutableCollections$AbstractImmutableSet.add(ImmutableCollections.java:281)  
at org.cloudhadoop.datetime.LamdaExpressionThisExample.main(LamdaExpressionThisExample.java:39)  

未修改的集合 不接受空值

Set.of("one", "two", null);  
ist.of("one", "two", null);  

输出是

Exception in thread "main" java.lang.NullPointerException  
at java.base/java.util.Objects.requireNonNull(Objects.java:221)  
at java.base/java.util.ImmutableCollections$ListN.(ImmutableCollections.java:234)  
at java.base/java.util.List.of(List.java:842)  
at org.cloudhadoop.datetime.LamdaExpressionThisExample.main(LamdaExpressionThisExample.java:39)  

如果Null值作为Map的键或值传递,则抛出java.lang.UnsupportedOperationException

Set strSet = Set.of("one", "two");  
strSet.add("three");  

输出是

Exception in thread "main" java.lang.UnsupportedOperationException  
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:71)  
at java.base/java.util.ImmutableCollections$AbstractImmutableSet.add(ImmutableCollections.java:281)  
at org.cloudhadoop.datetime.LamdaExpressionThisExample.main(LamdaExpressionThisExample.java:39)  

继承性

这些静态方法不能被重写。我们不能使用子类实现或实例类型来使用它们。它们只能使用接口名称来调用。

Collection Factory静态方法的特点:

  • 它返回未修改的集合
  • 如果元素是序列化的,返回的集合也是序列化的
  • 在Map中不允许有空的键和值
  • 在List和Set中不允许有空值
  • 这些集合是不可变的,任何可变的方法(从集合中添加/修改/删除元素)都会引发不支持的操作异常。
  • 在Set中不允许有重复的元素,而且排序是无序的
  • 列表允许重复,但返回的集合是基于原始插入顺序的。