加入收藏 | 设为首页 | 会员中心 | 我要投稿 宿州站长网 (https://www.0557zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Java9 集合工厂技巧

发布时间:2021-12-07 16:04:25 所属栏目:教程 来源:互联网
导读:使集合框架更便捷的工厂方法 JEP269中提议,为集合框架增添一些工厂方法,来使创建不可变集合类与含有少量元素的Map变得更加便捷。下文就为什么它们应运而生来展开详细的阐述。 集合框架增加工厂方法是必然的结果 Java饱受其语法臃肿的批评,比如,创建一个

使集合框架更便捷的工厂方法
 
JEP269中提议,为集合框架增添一些工厂方法,来使创建不可变集合类与含有少量元素的Map变得更加便捷。下文就为什么它们应运而生来展开详细的阐述。
 
集合框架增加工厂方法是必然的结果
 
Java饱受其语法臃肿的批评,比如,创建一个小而确定的集合类时(比如一个List),需要使用它的构造方法,然后将它的引用存放在局部变量中,通过引用来多次调用add()方法之后, 最后才来封装这个集合以获得不可变的视图。
 
早先的使用过程如下:
 
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list = Collections.unmodifiableList(list);
上面这个语法如此臃肿的例子在先前的版本中并不能够简化,不可变的静态集合必须在静态初始块中来填充,而不是使用更加方便的字段表达式。但是,也不得不提一下下面这些单语句表达式:
 
List<String> list1 =
   Collections.unmodifiableList(new ArrayList<>(Arrays.asList("a", "b", "c")));
 
List<String> list2 =
   Collections.unmodifiableList(new ArrayList<String>() {{ add("a"); add("b"); add("c"); }});
 
List<String> list3 =
   Collections.unmodifiableList(Stream.of("a", "b", "c").collect(toList()));
第一种方式比较扯淡,你走遍千山,你跨过弱水,只为取一瓜瓢饮,是的,你没有看错,你费尽千辛万苦只为了生成一个包含a,b,c三个元素的List,并且你要构建一个ArrayList还要仰仗Arrays.asList(“a”, “b”, “c”)这个乌七八黑的方式,它不好用不说,关键是它在短短的生命周期之后还要被GC,过程还是不可见的。。。
 
第二种好像看上去没那么扯淡,使用一个匿名内部类的实例初始化构造器来减少代码臃肿度,看上去很完美,但是可能会发生内存泄漏或者序列化的问题,因为它每次使用都会耗费额外的资源,还包含对封闭实例和任何捕获对象的隐藏引用。
 
第三种方式是使用Java8的Streams API来完成的,虽然代码没那么臃肿,但是过程中也涉及到了不必要的对象创建。此外,Streams API不能用来构建Map, 除非值是经键计算而来或者stream的元素包含键值对。
 
为解决这些问题,JEP186提议了集合字面量的概念,集合字面量是一种句法表达式,采用一种类数组的方式,来创建List、Map或者其它的集合类,下面是其原始类型的简明表达方式:
 
List<String> list = #[ "a", "b", "c" ];
没有任何新的语言特性,一切就像我们所思所想那样简明,但是这种集合字面量为什么没有被整合到Java9中去呢?取而代之的是,Java9采用了工厂方法来替代它,这其实是为了使语言改动尽量最小化,采用现有的方式,生产语法糖来达到这个目的的。
 
如此,集合工厂方法应运而生了。
 
一起来看看集合工厂方法
 
JEP 269的工厂方法受到类java.util.Collection和java.util.EnumSet类中的类似工厂方法的启发。 Collection提供用于创建空List,java.util.Set和Map的工厂方法,以及创建具有一个元素或键值对的单例List,Set和Map。 EnumSet提供了几个重载的of(…)工厂方法,它们采用固定或可变数量的参数,是为了更方便地创建指定元素的EnumSet。Java 9中的EnumSet模型的of()方法提供一致和通用的方式来创建包含任意类型对象的List,Set和Map。
 
以下工厂方法已添加到List接口中:
 
static <E> List<E> of()
static <E> List<E> of(E e1)
static <E> List<E> of(E e1, E e2)
static <E> List<E> of(E e1, E e2, E e3)
static <E> List<E> of(E e1, E e2, E e3, E e4)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
static <E> List<E> of(E... elements)
以下工厂方法已添加到Set接口中:
 
static <E> Set<E> of()
static <E> Set<E> of(E e1)
static <E> Set<E> of(E e1, E e2)
static <E> Set<E> of(E e1, E e2, E e3)
static <E> Set<E> of(E e1, E e2, E e3, E e4)
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5)
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6)
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
static <E> Set<E> of(E... elements)
在每个方法列表中, 第一个方法创建一个空的不可修改的集合。接下来的10个方法可创建1-10个元素的不可修改集合。尽管这些方法比较混乱,但它们避免了final类型的可变参方法产生的数组分配,初始化和垃圾回收开销,这种方法还支持任意大小的集合。
 
以下是List和Set的示例:
 
import java.util.List;
import java.util.Set;
 
public class ColDemo
{
   public static void main(String[] args)
   {
      List<String> fruits = List.of("apple", "orange", "banana");
      for (String fruit: fruits)
         System.out.println(fruit);
      try
      {
         fruits.add("pear");
      }
      catch (UnsupportedOperationException uoe)
      {
         System.err.println("unable to modify fruits list");
      }
 
      Set<String> marbles = Set.of("aggie", "alley", "steely");
      for (String marble: marbles)
         System.out.println(marble);
      try
      {
         marbles.add("swirly");
      }
      catch (UnsupportedOperationException uoe)
      {
         System.err.println("unable to modify marbles set");
      }
   }
}
运行后输出:
 
apple
orange
banana
unable to modify fruits list
steely
alley
aggie
unable to modify marbles set
以下工厂方法则添加到Map接口中:
 
static <K,V> Map<K,V>
   of()
static <K,V> Map<K,V>
   of(K k1, V v1)
static <K,V> Map<K,V>
   of(K k1, V v1, K k2, V v2)
static <K,V> Map<K,V>
   of(K k1, V v1, K k2, V v2, K k3, V v3)
static <K,V> Map<K,V>
   of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4)
static <K,V> Map<K,V>
   of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5    
static <K,V> Map<K,V>
   of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6)

(编辑:宿州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章