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个元素.
- 5月前1 #
- 5月前2 #
您怀疑,這是一項效能增強. Vararg方法"在幕後"建立一个陣列,並且拥有直接采用1-10个引數的方法可以避免這種多餘的陣列建立。
- 5月前3 #
您可能会發現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所有者自己在另一个答案的註釋中確认了)。
- 5月前4 #
此模式用於優化接受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例項的代碼可能如下所示: