[英]Java 8 streams and varargs
根據Effective Java 2nd Ed ,當你想編寫一個允許varargs的方法簽名但仍然強制你在編譯時只有一個元素時,你應該這樣編寫方法簽名:
public void something(String required, String ... additional) {
//... do what you want to do
}
如果我想要傳輸所有這些元素,我一直在做這樣的事情:
public void something(String required, String ... additional) {
Stream<String> allParams =
Stream.concat(Stream.of(required), Stream.of(additional));
//... do what you want to do
}
這感覺非常不優雅和浪費,特別是因為我正在創建一個1流並將其與另一個連接。 有更清潔的方法嗎?
這是一種在不創建兩個Streams
情況下執行此操作的方法,盡管您可能不喜歡它。
Stream.Builder<String> builder = Stream.<String>builder().add(required);
for (String s : additional) {
builder.add(s);
}
Stream<String> allParams = builder.build();
不幸的是,Java可能非常冗長。 但緩解這種情況的另一個選擇是簡單地使用靜態導入。 在我看來,它不會使您的代碼不那么清晰,因為每個方法都與流相關。
Stream<String> allParams =
concat(of(required), of(additional));
組合流沒有任何問題。 這些對象是輕量級的,因為它們只引用源數據,但不復制數組內容等數據。 如果實際有效載荷也非常小,那么這種輕量級對象的成本可能才有意義。 可以使用專門的,語義上等效的重載來處理這樣的場景:
public void something(String required, String ... additional) {
somethingImpl(Stream.concat(Stream.of(required), Stream.of(additional)));
}
public void something(String required) {
somethingImpl(Stream.of(required));
}
public void something(String required, String second) {
somethingImpl(Stream.of(required, second));
}
private void somethingImpl(Stream<String> allParams) {
//... do what you want to do
}
因此,在只有一個參數的情況下,您不僅要保存Stream
實例,還要保存varargs數組(類似於Stream.of
的重載)。 這是一種常見模式,例如參見EnumSet.of
重載。
但是,在很多情況下,即使這些簡單的重載也不是必需的,並且可能被認為是過早的優化(像JRE這樣的庫提供它們,因為如果需要,應用程序開發人員不可能添加它們)。 如果something
是應用程序而不是庫的一部分,則除非分析器告訴您該參數處理導致瓶頸,否則不應添加它們。
如果您願意使用Guava,可以使用Lists.asList(required, additional).stream()
。 創建該方法是為了簡化具有最低要求慣用語的varargs。
旁注,我認為圖書館真的很有用,但當然因為這個而添加它並不是一個好主意。 檢查文檔 ,看看它是否對您有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.