StreamToMap是一個非常有用和高效的Java 8中Stream API方法。它允許將一個Stream轉換成一個Map。本文將從多個方面為大家詳細講解StreamToMap的使用方法和實際應用場景。
一、StreamToMap的基本使用
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Map<Integer, Integer> map = list.stream().collect(Collectors.toMap(i -> i, i -> i * i));
System.out.println(map);
上面的代碼展示了如何使用StreamToMap方法將一個List轉換成一個Map。在這個例子中,我們傳遞了一個lambda表達式i -> i作為鍵值和一個lambda表達式i -> i * i作為值。
接下來,我們將解釋StreamToMap方法一些重要的參數。
二、keyMapper和valueMapper參數
這兩個參數是StreamToMap方法中最重要的參數。使用keyMapper和valueMapper可以讓我們更好地控制轉換過程,從而將Stream轉換成我們需要的形式。
1、keyMapper參數
keyMapper參數是一個Function類型,它以流中的元素為輸入,返回值作為Map的鍵。例如:
List<String> list = Arrays.asList("a", "b", "c");
Map<String, Integer> map = list.stream().collect(Collectors.toMap(Function.identity(), String::length));
System.out.println(map);
上面的代碼中,我們使用了Function.identity()作為keyMapper參數。這表示在Java 8中引入的靜態方法Function.identity(),該方法返回一個接收任何對象並返回該對象的身份的Lambda表達式。
2、valueMapper參數
與keyMapper參數類似,valueMapper參數也是一個Function類型,它將流中的元素轉換成Map的值。我們可以使用Java 8中的方法引用符號來簡化代碼:
List<Integer> list = Arrays.asList(1, 2, 3, 4);
Map<Integer, Double> map = list.stream().collect(Collectors.toMap(i -> i, Math::sqrt));
System.out.println(map);
這會以Math.sqrt()方法的輸出作為Map的值。
三、mergeFunction參數
如果在轉換過程中有兩個或更多個元素具有相同的鍵,則將會拋出IllegalStateException
,在這種情況下,我們可以使用mergeFunction參數來控制這種情況的處理方式。
Map<Integer, String> map = new HashMap<>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");
map.put(2, "z");
Map<Integer, String> newMap = map.entrySet()
.stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(value1, value2) -> value1 + value2)
);
System.out.println(newMap);
在這個例子中,我們使用mergeFunction參數將map中鍵為2的String合併成”bz”。
四、當Stream中的元素為null時如何處理
在Java 8中,Stream API是不允許出現null值的。因此,如果Stream中出現了null值,那麼StreamToMap方法將拋出NullPointerException
異常。為了避免這種情況,我們可以使用Stream的過濾功能:
List<String> list = Arrays.asList("a", "b", null, "c");
Map<String, Integer> map = list.stream()
.filter(Objects::nonNull)
.collect(Collectors.toMap(Function.identity(), String::length));
System.out.println(map);
在這個例子中,我們使用了Objects.nonNull方法來過濾null值。
五、實際應用場景
StreamToMap方法在實際應用中非常常用,下面是幾個實際場景的例子。
1、List轉Map
假設我們有一個List,它的元素是Employee對象。Employee對象包含id、name和age屬性。現在,我們想根據員工ID將這個List轉換成一個Map。
class Employee {
private int id;
private String name;
private int age;
// 省略 getter 和 setter 方法
}
List<Employee> employees = Arrays.asList(
new Employee(1, "Alice", 23),
new Employee(2, "Bob", 25),
new Employee(3, "Chris", 21),
new Employee(4, "David", 22),
new Employee(5, "Emma", 26)
);
Map<Integer, Employee> employeeMap = employees
.stream()
.collect(Collectors.toMap(Employee::getId, Function.identity()));
System.out.println(employeeMap);
在這個例子中,使用了Employee::getId作為keyMapper參數,而使用了Function.identity()作為valueMapper參數。
2、Map轉List
我們同樣可以使用類似的方式將Map轉換成List。
Map<Integer, String> map = new HashMap<>();
map.put(1, "Alice");
map.put(2, "Bob");
map.put(3, "Chris");
map.put(4, "David");
map.put(5, "Emma");
List<String> names = map.entrySet()
.stream()
.map(Map.Entry::getValue)
.collect(Collectors.toList());
System.out.println(names);
在這個例子中,我們使用了.map(Map.Entry::getValue)將Map.Entry對象映射成Map的值。
3、List轉Map,並且values包含多個對象
我們可以使用更高級的技巧將一個List轉換成一個Map,並且Map的值包含多個對象。
List<Employee> employees = Arrays.asList(
new Employee(1, "Alice", 23),
new Employee(2, "Bob", 25),
new Employee(3, "Chris", 21),
new Employee(4, "David", 22),
new Employee(5, "Emma", 26)
);
Map<Integer, List<String>> employeeMap = employees
.stream()
.collect(Collectors.toMap(
Employee::getId,
e -> new ArrayList<>(Arrays.asList(e.getName(), String.valueOf(e.getAge())))
));
System.out.println(employeeMap);
在這個例子中,我們使用了一個lambda表達式e -> new ArrayList<>(Arrays.asList(e.getName(), String.valueOf(e.getAge())))作為valueMapper參數。
六、總結
在Java 8中,Stream API提供了許多強大的方法,StreamToMap是其中之一。StreamToMap方法允許我們將Stream轉換成Map,並且對於相同的鍵提供了多種處理方式。它的使用方法非常簡單,只需要了解基本的參數就可以快速掌握。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/279038.html