基於流建立地圖
簡單的情況沒有重複的鍵
Stream<String> characters = Stream.of("A", "B", "C");
Map<Integer, String> map = characters
.collect(Collectors.toMap(element -> element.hashCode(), element -> element));
// map = {65=A, 66=B, 67=C}
為了使事情更具說明性,我們可以在 Function
介面中使用靜態方法 - Function.identity()
。我們可以用 Function.identity()
替換這個 lambda element -> element
。
可能存在重複鍵的情況
Collectors.toMap
的 javadoc 宣告:
如果對映的鍵包含重複項(根據
Object.equals(Object)
),則在執行收集操作時會丟擲IllegalStateException
。如果對映的鍵可能有重複,請改用toMap(Function, Function, BinaryOperator)
。
Stream<String> characters = Stream.of("A", "B", "B", "C");
Map<Integer, String> map = characters
.collect(Collectors.toMap(
element -> element.hashCode(),
element -> element,
(existingVal, newVal) -> (existingVal + newVal)));
// map = {65=A, 66=BB, 67=C}
傳遞給 Collectors.toMap(...)
的 BinaryOperator
生成在碰撞情況下儲存的值。它可以:
- 返回舊值,以便流中的第一個值優先,
- 返回新值,以便流中的最後一個值優先,或
- 結合新舊值
按價值分組
當你需要執行等效的資料庫級聯分組依據操作時,可以使用 Collectors.groupingBy
。為了說明,下面建立了一個地圖,其中人們的姓名被對映到姓氏:
List<Person> people = Arrays.asList(
new Person("Sam", "Rossi"),
new Person("Sam", "Verdi"),
new Person("John", "Bianchi"),
new Person("John", "Rossi"),
new Person("John", "Verdi")
);
Map<String, List<String>> map = people.stream()
.collect(
// function mapping input elements to keys
Collectors.groupingBy(Person::getName,
// function mapping input elements to values,
// how to store values
Collectors.mapping(Person::getSurname, Collectors.toList()))
);
// map = {John=[Bianchi, Rossi, Verdi], Sam=[Rossi, Verdi]}