簡體   English   中英

Java 16的Stream.toList()和Stream.collect(Collectors.toList()的區別?

[英]Differences of Java 16's Stream.toList() and Stream.collect(Collectors.toList())?

JDK 16 現在直接在Stream實例上包含一個toList()方法 在之前的 Java 版本中,您始終必須使用collect方法並提供一個Collector實例。

新方法顯然要輸入更少的字符。 這兩種方法是否可以互換,還是應該注意細微差別?

var newList = someCollection.stream()
    .map(x -> mapX(x))
    .filter(x -> filterX(x))
    .toList();

// vs.

var oldList = someCollection.stream()
    .map(x -> mapX(x))
    .filter(x -> filterX(x))
    .collect(Collectors.toList());

(這個問題類似於會 Stream.toList() 比 Collectors.toList() 表現更好,但關注的是行為而不是(僅)性能。)

一個區別是Stream.toList()提供了一個不可變的List實現(類型ImmutableCollections.ListN不能添加或排序),類似於List.of()提供的,與可變的(可以更改和已排序) ArrayListStream.collect(Collectors.toList())提供。

演示:

import java.util.stream.Stream;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> list = Stream.of("Hello").toList();
        System.out.println(list);
        list.add("Hi");
    }
}

Output:

[Hello]
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142)
    at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:147)
    at Main.main(Main.java:8)

請查看這篇文章了解更多詳情。

更新:

有趣的是, Stream.toList()成功返回了一個包含null的列表。

import java.util.stream.Stream;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Object> list = Stream.of(null, null).toList();
        System.out.println(list);
    }
}

Output:

[null, null]

另一方面, List.of(null, null)拋出NullPointerException

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Object> list = List.of(null, null);
    }
}

Output:

Exception in thread "main" java.lang.NullPointerException
    at java.base/java.util.Objects.requireNonNull(Objects.java:208)
    at java.base/java.util.ImmutableCollections$List12.<init>(ImmutableCollections.java:453)
    at java.base/java.util.List.of(List.java:827)
    at Main.main(Main.java:5)

注意:我使用openjdk-16-ea+34_osx-x64編譯並執行了Java SE 16代碼。

有用的資源:

  1. JDK 錯誤# JDK-8180352
  2. 使用單個 null 參數調用 Java 可變參數方法?

Here is a small table that summarizes the differences between Stream.collect(Collectors.toList()) , Stream.collect(Collectors.toUnmodifiableList()) and Stream.toList() :

  • collect(toList()) :保證不可修改性 - 允許空值 -
  • collect(toUnmodifiableList()) :保證不可修改性 -的; 允許空值 -
  • toList() :保證不可修改性 -的; 允許空值 -

.collect(toList())toList()在創建的列表中元素的子類型兼容性方面表現不同

看看以下替代方案:

  • List<Number> old = Stream.of(0).collect(Collectors.toList()); 工作正常,盡管我們將 Integer 的stream收集到Number列表中。
  • List<Number> new = Stream.of(0).toList(); 是等效的 Java 16+ 版本,但它不能編譯( cannot convert from List<Integer> to List<Number> ;至少在 ecj 中,Eclipse ZD52387880E2EA223817A 編譯器)。

至少有兩種解決方法可以修復編譯錯誤:

  • 顯式轉換為所需類型List<Number> fix1 = Stream.of(0).map(Number.class::cast).toList();
  • 允許結果集合中的子類型: List<? extends Number> fix2 = Stream.of(0).toList(); List<? extends Number> fix2 = Stream.of(0).toList();

據我了解,根本原因如下:Java 16 toList()的泛型 T 與 Stream 本身的泛型 T 相同。 但是,Collectors.toList() 的泛型類型 T 是從賦值的左側傳播的。 如果這兩種類型不同,則在替換所有舊調用時可能會看到錯誤。

如何轉換 ArrayList<string> 至 ArrayList<object> using.collect(Collectors.toList() 在 Java stream<div id="text_translate"><p> 如何在 Java stream 中使用.collect(Collectors.toList()將ArrayList&lt;String&gt;轉換為ArrayList&lt;Object&gt;</p><p> 之前我用過</p><pre>CommonList = detailUtils.SelectIDValueGetterObservable(getActivity()).stream().forEach(i -&gt; CommonList.add(new foo(i));`</pre><p> 但是我遇到了這些<strong>副作用</strong></p><p> <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html" rel="nofollow noreferrer">https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html</a></p><p> 這建議.collect(Collectors.toList()</p><p> 我們該怎么做</p></div></object></string>

[英]How can I convert ArrayList<String> to ArrayList<Object> using .collect(Collectors.toList() in Java stream

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM