Java 9:什么是集合工厂方法?

Jac*_* G. 0 java collections factory literals java-9

Java 9的出现为Java的Collections API带来了许多新功能,其中一个是集合工厂方法.

它们是什么以及如何正确实施?

Jac*_* G. 9

注1:为了防止使用原始类型,我选择为下面提到的每个类提供一个泛型类型E,表示一个元素Collection<E>.

注2:这个答案可能会有所变化; 如果发生拼写错误,请编辑此帖子.

什么是收集工厂方法?

Java中的集合工厂方法是一种静态方法,它提供了一种初始化不可变 的简单方法Collection<E>.

作为不可变的,Collection<E>在初始化之后,不能在其内部添加,删除或修改元素.

在Java 9,提供了以下接口采集工厂方法:List<E>,Set<E>,和Map<K, V>

它们有什么改进?

直到Java 9,没有简单的通用方法来初始化Collection<E>具有初始元素/键值条目的方法.此前,被要求开发如下初始化它们(假设泛型类型E,KV已被替换Integer):

  • List<Integer>
    • 下面的方法可以说是最简单的List<Integer>用初始元素初始化a ,但结果只是a的视图List<Integer>; 我们无法添加或删除List<Integer>,但我们仍然可以使用修改现有元素List#set.
      • List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
    • 如果我们希望我们List<Integer>完全可变,那么我们必须将它传递给一个构造函数ArrayList<Integer>,例如:
      • List<Integer> mutableList = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
  • Set<Integer>
    • Set<Integer>需要更多的代码来以比初始要素初始化List<Integer>确实(作为看到List<Integer>需要初始化Set<Integer>,这在下面可以看到与初始元素).
      • Set<Integer> mutableSet = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
  • Map<Integer, Integer>
    • Map<Integer, Integer>使用初始键值条目初始化A 可能是最复杂的; 但是,有多种方法可以解决这个问题.
      • 一种方法是首先初始化一个空Map<Integer, Integer>并简单地调用Map#put以添加键值条目.
      • 另一种方法是使用带有两个花括号的匿名类,这仍然需要Map#put被调用.

我为什么要用它们?

我认为,收集工厂方法提供的显影剂具有初始化的简明方法List<E>,Set<E>Map<K, V>与初始要素/键-值条目,其可以由下面的实施例中可以看出.

使用的正确语法是什么?

为简单起见,这些例子将取代泛型类型E,K以及VInteger.

  • List<Integer>
    • List<Integer> list = List.of();
      • 初始化一个空的,不可变的List<Integer>.
    • List<Integer> list = List.of(1);
      • List<Integer>使用一个元素初始化一个不可变的.
    • List<Integer> list = List.of(1, 2);
      • List<Integer>使用两个元素初始化一个不可变的.
    • List<Integer> list = List.of(1, 2, 3, 4, 5, ...);
      • 使用List<Integer>可变数量的元素初始化不可变.
  • Set<Integer>
    • Set<Integer> set = Set.of();
      • 初始化一个空的,不可变的Set<Integer>.
    • Set<Integer> set = Set.of(1);
      • Set<Integer>使用一个元素初始化一个不可变的.
    • Set<Integer> set = Set.of(1, 2);
      • Set<Integer>使用两个元素初始化一个不可变的.
    • Set<Integer> set = Set.of(1, 2, 3, 4, 5, ...);
      • 使用Set<Integer>可变数量的元素初始化不可变.
  • Map<Integer, Integer>
    • Map<Integer, Integer> map = Map.of();
      • 初始化一个空的,不可变的Map<Integer, Integer>.
    • Map<Integer, Integer> map = Map.of(1, 2);
      • Map<Integer, Integer>使用一个键值条目初始化一个不可变项.
      • 请注意,键是1,值是2.
    • Map<Integer, Integer> map = Map.of(1, 2, 3, 4);
      • Map<Integer, Integer>使用两个键值条目初始化一个不可变项.
      • 请注意,键是13,值是24.
    • Map<Integer, Integer> map = Map.ofEntries(Map.entry(1, 2), Map.entry(3, 4), ...);
      • 使用Map<Integer, Integer>可变数量的键值条目初始化不可变.

如您所见,这种新的初始化方法需要的代码少于其前辈.

我可以使用集合工厂方法来创建可变对象吗?

Collection<E>通过收集工厂方法创建本质上是不可变的,但是我们可以将它们传递给的一个实现方式的构造函数Collection<E>产生一个可变的版本:

  • List<Integer>
    • List<Integer> mutableList = new ArrayList<>(List.of(1, 2, 3, 4, 5));
  • Set<Integer>
    • Set<Integer> mutableSet = new HashSet<>(Set.of(1, 2, 3, 4, 5));
  • Map<Integer, Integer>
    • Map<Integer, Integer> mutableMap = new HashMap<>(Map.of(1, 2, 3, 4));

  • `Map`在Collection API中.集合不仅仅是实现`Collection <E>`的东西 (5认同)
  • 而且,我怀疑这可以称为集合*文字*.它们只是集合工厂方法,可以轻松创建集合**而无需**集合文字. (4认同)
  • @Jacob我建议将问题重命名为**"Java 9:什么是收集工厂方法?"**根据JEP 269.收集文字在JEP 186中提出并被拒绝. (2认同)