Java9中集合工厂方法的示例分析

发布时间:2021-09-05 13:18:59 作者:小新
来源:亿速云 阅读:132

这篇文章给大家分享的是有关Java9中集合工厂方法的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

使集合框架更便捷的工厂方法

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()));

为解决这些问题,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)
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, K k7, V v7    
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, K k7, V v7, 
      K k8, V v8)
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, K k7, V v7, 
      K k8, V v8, K k9, V v9)
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, K k7, V v7, 
      K k8, V v8, K k9, V v9, K k10, V v10)
static <K,V> Map<K,V> 
   ofEntries(Map.Entry<? extends K,? extends V>... entries)

第一个方法创建了一个空的不可变的Map,接下来10个方法创建包含1-10和键值对的Map,尽管这些方法比较混乱,但它们避免了final类型的可变参方法产生的数组分配,初始化和垃圾回收开销,且支持任意大小的Map。

虽然Map的可变参数方法近似List和Set的,但是它的每个键值对必须被包装起来,下面这个方法可以方便地将包装键值对转换为Map标准键值对:

Map.Entry<K,V> entry(K k, V v)

下面是Map的ofEntries() 和entry()方法的示例

import java.util.Map;
import static java.util.Map.entry;
public class MapDemo
{
   public static void main(String[] args)
   {
      Map<String, String> capCities = 
         Map.ofEntries(entry("Manitoba", "Winnipeg"), 
                       entry("Alberta", "Edmonton"));
      capCities.forEach((k, v) -> 
                        System.out.printf("Key = %s, Value = %s%n", k, v));
      try
      {
         capCities.put("British Columbia", "Victoria");
      }
      catch (UnsupportedOperationException uoe)
      {
         System.err.println("unable to modify capCities map");
      }
   }
}

运行后输出:

Key = Alberta, Value = Edmonton
Key = Manitoba, Value = Winnipeg
unable to modify capCities map

注意,未来的JDK版本可能会让开发者指定值类型来减少包装键值对所带来的性能开销,从entry()方法可以看出,通过它返回一个新的实现自Map.Entry的具体引用类型,我想这是为了后面把潜在特性迁移到值类型中去设下的铺垫吧。

感谢各位的阅读!关于“Java9中集合工厂方法的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

推荐阅读:
  1. js遍历集合的示例分析
  2. Java中Map集合的示例分析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java9

上一篇:微信JSSDK如何配置

下一篇:React的React.FC与React.Component的用法

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》