Java 9随附了便捷工厂方法,用于创建不可变列表.最后,列表创建非常简单:
List<String> list = List.of("foo", "bar");
但是此方法有12种重载版本,其中11种包含0到10个元素,而1种包含var args。
static <E> List<E> of(E... elements)
Set
也是如此
和
Map
既然有var args方法,那么拥有额外的11种方法有什么意义?
我认为是var-args创建一个数组,因此其他11种方法可以跳过创建额外对象的过程,并且在大多数情况下,可以使用0-10个元素.
- 2021-1-111 #
- 2021-1-112 #
您怀疑,这是一项性能增强. Vararg方法"在幕后"创建一个数组,并且拥有直接采用1-10个参数的方法可以避免这种多余的数组创建。
- 2021-1-113 #
您可能会发现Josh Bloch的项目42的以下段落 有效的Java(第二版):
Every invocation of a varargs method causes an array allocation and initialization. If you have determined empirically that you can’t afford this cost but you need the flexibility of varargs, there is a pattern that lets you have your cake and eat it too. Suppose you’ve determined that 95 percent of the calls to a method have three or fewer parameters. Then declare five overloadings of the method, one each with zero through three ordinary parameters, and a single varargs method for use when the number of arguments exceeds three [...]
您也可以反过来查看它.由于varargs方法可以接受数组,因此该方法可以用作将数组转换为
List
的替代方法。String []strArr = new String[]{"1","2"}; List<String> list = List.of(strArr);
此方法的替代方法是使用
Arrays.asList
但对List
所做的任何更改 在这种情况下将反映在数组中,而List.of
则不然 .因此,您可以使用List.of
当你不想要List
时 和要同步的阵列。Note 规范中给出的理由对我来说似乎是微优化. (这已经由API所有者自己在另一个答案的注释中确认了)。
- 2021-1-114 #
此模式用于优化接受varargs参数的方法.
如果您能确定大多数时间只使用其中的几个,则您可能想定义一个方法重载,其中包含最常用的参数:
public void foo(int num1); public void foo(int num1, int num2); public void foo(int num1, int num2, int num3); public void foo(int... nums);
这将帮助您避免在调用varargs方法时创建数组.用于性能优化的模式:
List<String> list = List.of("foo", "bar"); // Delegates call here static <E> List<E> of(E e1, E e2) { return new ImmutableCollections.List2<>(e1, e2); // Constructor with 2 parameters, varargs avoided! }
更有趣的是,从3个参数开始,我们再次委托给varargs构造函数:
static <E> List<E> of(E e1, E e2, E e3) { return new ImmutableCollections.ListN<>(e1, e2, e3); // varargs constructor }
目前看来这很奇怪,但是正如我可能猜到的-这是为将来的改进保留的,并且作为一种选择,所有构造函数的潜在重载
List3(3 params), List7(7 params)...
等
相关问题
- java:如何使用可变参数和反射javareflectionvariadicfunctions2021-01-11 20:57
- java:用于 '? 延伸'和'? 超级类集合javagenericscollections2021-01-11 17:28
来自JEP文档本身-
Description -
编辑-要添加动机,也正如@CKing在评论中所提到的:
Non-Goals -
Motivation -
创建一个小的,不可修改的集合(例如,一个集合)包括构造它,将其存储在局部变量中,并对其多次调用add(),然后将其包装。
通过结合流工厂方法和收集器,可以使用Java 8 Stream API来构造小的收集器。
通过提供用于创建小型集合实例的库API可以获得集合文字的大部分好处,与更改语言相比,这大大降低了成本和风险.例如,创建一个小的Set实例的代码可能如下所示: