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)
Set
和Map
同样如此。
由于有一个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