Java 9中集合的重载便利工厂方法的重点是什么


问题内容

Java 9带有用于创建不可变列表的便捷工厂方法。最后,创建列表很简单:

List<String> list = List.of("foo", "bar");

但是此方法有12个重载版本,其中11个包含0到10个元素,而一个具有var args。

static <E> List<E>  of(E... elements)

同样是与案件Set和Map。

既然有一个var args方法,那么拥有额外的11种方法有什么意义呢?

我认为是var-args创建一个数组,因此其他11种方法可以跳过创建额外对象的过程,并且在大多数情况下,可以使用0-10个元素。还有其他原因吗?


问题答案:

从JEP文档本身-

说明-

这些将包括varargs重载,因此对集合大小没有固定的限制。但是,可以将这样创建的集合实例调整为较小的大小。将提供最多十个元素的特殊情况的API(固定参数重载)。虽然这在API中引入了一些混乱,但它避免了由varargs调用引起的数组分配,初始化和垃圾回收开销。重要的是,无论调用了fixed-arg还是varargs重载,调用站点的源代码都是相同的。

编辑-要添加动力,也已通过@CKing在评论中提到:

非目标-

支持具有任意数量的元素的高性能,可伸缩集合不是目标。重点是小收藏。

动机-

创建一个小的,不可修改的集合(例如,一个集合)包括构造它,将其存储在局部变量中,并对其多次调用add(),然后将其包装。

Set<String> set = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("a", "b", "c")));

通过结合流工厂方法和收集器,可以使用Java 8 Stream API来构建小型收集。

// Java 8
Set<String> set1 = Collections.unmodifiableSet(Stream.of("a", "b", "c").collect(Collectors.toSet()));

通过提供用于创建小型集合实例的库API可以获得集合文字的大部分好处,与更改语言相比,这些API的成本和风险大大降低。例如,创建一个小的Set实例的代码可能如下所示:

// Java 9 
Set set2 = Set.of("a", "b", "c");