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

Java 9提供了用于创建不可变列表的便捷工厂方法。 最后,列表创建如下简单:

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

但是这个方法有12个重载版本,11个有0到10个元素,一个有var args。

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

SetMap同样如此。

由于有一个var args方法,有多余的11个方法有什么意义?

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


从JEP文件本身 -

说明 -

这些将包括可变参数重载,所以对集合大小没有固定的限制。 但是,创建的集合实例可能会针对较小的尺寸进行调整。 将提供多达10个元素的特例API(固定参数重载)。 虽然这在API中引入了一些混乱,但它避免了由可变参数调用引起的数组分配,初始化和垃圾收集开销。 值得注意的是,无论是否调用固定参数或可变参数超载,呼叫站点的源代码都是相同的。


编辑 - 为了增加动力,也正如@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来获得,与更改语言相比,成本和风险显着降低。 例如,创建小型Set实例的代码可能如下所示:

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

如你所怀疑的那样,这是一项性能提升。 可变参数方法创建一个“底层”数组,并且具有直接使用1-10个参数的方法避免了冗余数组的创建。


你可能会发现Josh Bloch的Effective Java(第2版)第42项的以下段落的启示:

每次调用varargs方法都会导致数组分配和初始化。 如果您已经凭经验确定您无法承担这笔费用,但您需要可变参数的灵活性,则有一种模式可让您获得蛋糕并将其吃掉。 假设你已经确定95%的方法调用有三个或更少的参数。 然后声明该方法的五个重载,每一个都有零到三个普通参数,并且当参数个数超过三个时使用一个可变varargs方法[...]

链接地址: http://www.djcxy.com/p/27725.html

上一篇: What is the point of overloaded Convenience Factory Methods for Collections in Java 9

下一篇: Why doesn't Java offer operator overloading?