Java Stream魔法:List秒變Map,重復(fù)鍵值巧應(yīng)對(duì)
一、Stream API 初相識(shí)
圖片
在 Java 8 的世界里,Stream API 無(wú)疑是一顆璀璨的明星,為我們處理集合數(shù)據(jù)帶來(lái)了前所未有的便捷。以往,我們?cè)诓僮骷蠒r(shí),常常需要編寫(xiě)冗長(zhǎng)的循環(huán)和復(fù)雜的條件判斷,代碼不僅繁瑣,而且可讀性欠佳。但 Stream API 的出現(xiàn),徹底改變了這一局面。它以一種更為簡(jiǎn)潔、高效的方式,讓我們能夠輕松地對(duì)集合進(jìn)行過(guò)濾、映射、排序等操作,就像給我們的代碼插上了翅膀,使其更加優(yōu)雅和強(qiáng)大。
Stream API 就像是一條神奇的流水線(xiàn),集合中的元素就像流水線(xiàn)上的產(chǎn)品,我們可以在這條流水線(xiàn)上對(duì)元素進(jìn)行各種加工處理。它支持鏈?zhǔn)秸{(diào)用,多個(gè)操作可以一氣呵成,讓代碼變得簡(jiǎn)潔明了,就像在講述一個(gè)清晰的故事。而且,Stream API 還支持并行處理,能充分利用多核處理器的優(yōu)勢(shì),大大提高處理效率,在面對(duì)海量數(shù)據(jù)時(shí),其優(yōu)勢(shì)尤為明顯。
二、List 華麗變身 Map
圖片
(一)基礎(chǔ)轉(zhuǎn)換操作
了解了 Stream API 的強(qiáng)大之處后,我們就來(lái)看看如何利用它將 List 轉(zhuǎn)換為 Map。在 Java 中,使用 Stream API 的 Collectors.toMap () 方法可以輕松實(shí)現(xiàn)這一轉(zhuǎn)換。下面通過(guò)一個(gè)具體的代碼示例來(lái)詳細(xì)說(shuō)明。
假設(shè)我們有一個(gè)包含用戶(hù)信息的 List,每個(gè)用戶(hù)對(duì)象包含 id、name 和 age 等屬性,現(xiàn)在我們想將這個(gè) List 轉(zhuǎn)換為以用戶(hù) id 為鍵,用戶(hù)對(duì)象為值的 Map。代碼如下:
import java.util.*;import java.util.stream.Collectors;class User {private Integer id;private String name;private Integer age;public User(Integer id, String name, Integer age) {this.id = id;this.name = name;this.age = age;}public Integer getId() {return id;}public String getName() {return name;}public Integer getAge() {return age;}@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}}public class ListToMapExample {public static void main(String[] args) {// 創(chuàng)建一個(gè)包含用戶(hù)信息的ListList<User> userList = new ArrayList<>();userList.add(new User(1, "Alice", 25));userList.add(new User(2, "Bob", 30));userList.add(new User(3, "Charlie", 28));// 使用Stream API將List轉(zhuǎn)換為MapMap<Integer, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, // 提取用戶(hù)id作為Map的鍵Function.identity() // 直接使用用戶(hù)對(duì)象作為Map的值));// 輸出轉(zhuǎn)換后的MapuserMap.forEach((id, user) -> System.out.println("id: " + id + ", user: " + user));}}
在上述代碼中,Collectors.toMap()方法接收兩個(gè)參數(shù):第一個(gè)參數(shù)User::getId是一個(gè)函數(shù),用于從用戶(hù)對(duì)象中提取 id 作為 Map 的鍵;第二個(gè)參數(shù)Function.identity()表示直接使用用戶(hù)對(duì)象作為 Map 的值。通過(guò)這種方式,我們成功地將 List 轉(zhuǎn)換為了 Map。
(二)實(shí)際場(chǎng)景應(yīng)用
在實(shí)際項(xiàng)目中,將 List 轉(zhuǎn)換為 Map 有著廣泛的應(yīng)用場(chǎng)景。比如,在一個(gè)電商系統(tǒng)中,我們從數(shù)據(jù)庫(kù)中查詢(xún)出所有商品的信息,存儲(chǔ)在一個(gè) List 中。如果我們需要根據(jù)商品 id 快速查找商品信息,就可以將這個(gè) List 轉(zhuǎn)換為以商品 id 為鍵,商品對(duì)象為值的 Map,這樣在后續(xù)的操作中,通過(guò)商品 id 獲取商品信息的時(shí)間復(fù)雜度將從 O (n) 降低到 O (1),大大提高了查詢(xún)效率。
再比如,在處理日志數(shù)據(jù)時(shí),我們可能會(huì)將日志信息存儲(chǔ)在 List 中,每一條日志記錄包含時(shí)間、日志級(jí)別、日志內(nèi)容等信息。如果我們想要根據(jù)日志級(jí)別對(duì)日志進(jìn)行分組統(tǒng)計(jì),就可以將 List 轉(zhuǎn)換為以日志級(jí)別為鍵,包含該級(jí)別日志記錄的 List 為值的 Map,然后對(duì)每個(gè)分組進(jìn)行相應(yīng)的統(tǒng)計(jì)操作。
三、解決重復(fù)鍵值的挑戰(zhàn)
圖片
在進(jìn)行 List 到 Map 的轉(zhuǎn)換時(shí),我們常常會(huì)遇到一個(gè)棘手的問(wèn)題 —— 重復(fù)鍵值。由于 Map 的特性要求鍵必須唯一,當(dāng) List 中存在多個(gè)元素的鍵值相同時(shí),直接使用Collectors.toMap()方法就會(huì)拋出IllegalStateException異常,提示 “Duplicate key”。這就好比我們要把一群人按照身份證號(hào)(假設(shè)鍵為身份證號(hào))分組,而如果出現(xiàn)了兩個(gè)相同的身份證號(hào),系統(tǒng)就會(huì)陷入混亂,不知道該如何處理。接下來(lái),我們就一起探討一下應(yīng)對(duì)這個(gè)挑戰(zhàn)的策略。
(一)拋出異常策略
默認(rèn)情況下,當(dāng)遇到重復(fù)鍵值時(shí),Collectors.toMap()方法會(huì)拋出IllegalStateException異常。這是因?yàn)樵诖蠖鄶?shù)情況下,重復(fù)鍵值可能意味著數(shù)據(jù)存在錯(cuò)誤或不一致性,系統(tǒng)無(wú)法自動(dòng)決定如何處理這些重復(fù)的鍵值。例如,在上述用戶(hù)信息的例子中,如果有兩個(gè)用戶(hù)的 id 相同,這顯然是不符合業(yè)務(wù)邏輯的,拋出異??梢约皶r(shí)提醒開(kāi)發(fā)者去檢查和修正數(shù)據(jù)。
(二)自定義合并策略
當(dāng)我們確定重復(fù)鍵值是合理的業(yè)務(wù)情況,并且需要對(duì)其進(jìn)行處理時(shí),就可以使用Collectors.toMap()方法的另一個(gè)重載版本,它接收三個(gè)參數(shù):鍵映射函數(shù)、值映射函數(shù)以及合并函數(shù)。通過(guò)自定義合并函數(shù),我們可以靈活地處理重復(fù)鍵值的情況。
- 保留舊值:
保留舊值是指當(dāng)遇到重復(fù)鍵時(shí),不更新原有的值,保持 Map 中已存在的值不變。在一些場(chǎng)景中,我們希望優(yōu)先保留最早出現(xiàn)的數(shù)據(jù),因?yàn)樗赡芫哂懈叩膬?yōu)先級(jí)或更重要的信息。比如在記錄用戶(hù)的登錄歷史時(shí),我們更關(guān)注用戶(hù)首次登錄的時(shí)間,所以當(dāng)出現(xiàn)重復(fù)的用戶(hù) id 時(shí),保留首次登錄時(shí)間,忽略后續(xù)相同 id 的登錄時(shí)間記錄。
import java.util.*;import java.util.stream.Collectors;class User {private Integer id;private String name;private Integer age;public User(Integer id, String name, Integer age) {this.id = id;this.name = name;this.age = age;}public Integer getId() {return id;}public String getName() {return name;}public Integer getAge() {return age;}@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}}public class ListToMapMergeExample {public static void main(String[] args) {List<User> userList = new ArrayList<>();userList.add(new User(1, "Alice", 25));userList.add(new User(1, "Bob", 30)); // 重復(fù)的idMap<Integer, User> userMap = userList.stream().collect(Collectors.toMap(User::getId,Function.identity(),(existing, replacement) -> existing // 保留舊值));userMap.forEach((id, user) -> System.out.println("id: " + id + ", user: " + user));}}
在上述代碼中,合并函數(shù)(existing, replacement) -> existing表示當(dāng)遇到重復(fù)鍵時(shí),直接返回已存在的值(即保留舊值)。運(yùn)行這段代碼,我們會(huì)發(fā)現(xiàn) Map 中最終保留的是第一個(gè)用戶(hù) “Alice” 的信息,而第二個(gè)用戶(hù) “Bob” 的信息被忽略了。
- 選擇新值:
選擇新值策略則與保留舊值相反,當(dāng)遇到重復(fù)鍵時(shí),使用新的值替換 Map 中已有的值。在某些場(chǎng)景下,新的數(shù)據(jù)可能更具有時(shí)效性或準(zhǔn)確性,我們需要及時(shí)更新 Map 中的值。比如在實(shí)時(shí)更新用戶(hù)的在線(xiàn)狀態(tài)時(shí),新的狀態(tài)信息更能反映用戶(hù)當(dāng)前的實(shí)際情況,所以當(dāng)出現(xiàn)重復(fù)的用戶(hù) id 時(shí),用新的在線(xiàn)狀態(tài)信息替換舊的。
import java.util.*;import java.util.stream.Collectors;class User {private Integer id;private String name;private Integer age;public User(Integer id, String name, Integer age) {this.id = id;this.name = name;this.age = age;}public Integer getId() {return id;}public String getName() {return name;}public Integer getAge() {return age;}@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}}public class ListToMapMergeExample {public static void main(String[] args) {List<User> userList = new ArrayList<>();userList.add(new User(1, "Alice", 25));userList.add(new User(1, "Bob", 30)); // 重復(fù)的idMap<Integer, User> userMap = userList.stream().collect(Collectors.toMap(User::getId,Function.identity(),(existing, replacement) -> replacement // 選擇新值));userMap.forEach((id, user) -> System.out.println("id: " + id + ", user: " + user));}}
這里的合并函數(shù)(existing, replacement) -> replacement表示當(dāng)鍵重復(fù)時(shí),返回新的值。運(yùn)行代碼后,Map 中最終保留的是第二個(gè)用戶(hù) “Bob” 的信息,“Alice” 的信息被替換掉了。
- 合并值:
除了保留舊值和選擇新值,我們還可以將重復(fù)鍵的值進(jìn)行合并。這種策略適用于需要對(duì)重復(fù)數(shù)據(jù)進(jìn)行匯總或整合的場(chǎng)景。例如,我們有一個(gè)商品銷(xiāo)售記錄的 List,每個(gè)記錄包含商品 id、銷(xiāo)售數(shù)量和銷(xiāo)售金額等信息。當(dāng)將這個(gè) List 轉(zhuǎn)換為以商品 id 為鍵的 Map 時(shí),如果存在相同商品 id 的記錄,我們可以將銷(xiāo)售數(shù)量和銷(xiāo)售金額進(jìn)行累加,以得到該商品的總銷(xiāo)售數(shù)量和總銷(xiāo)售金額。
import java.util.*;import java.util.stream.Collectors;class SaleRecord {private Integer productId;private Integer quantity;private Double amount;public SaleRecord(Integer productId, Integer quantity, Double amount) {this.productId = productId;this.quantity = quantity;this.amount = amount;}public Integer getProductId() {return productId;}public Integer getQuantity() {return quantity;}public Double getAmount() {return amount;}@Overridepublic String toString() {return "SaleRecord{" +"productId=" + productId +", quantity=" + quantity +", amount=" + amount +'}';}}public class ListToMapMergeValueExample {public static void main(String[] args) {List<SaleRecord> saleRecordList = new ArrayList<>();saleRecordList.add(new SaleRecord(1, 5, 100.0));saleRecordList.add(new SaleRecord(1, 3, 60.0)); // 重復(fù)的productIdMap<Integer, SaleRecord> saleRecordMap = saleRecordList.stream().collect(Collectors.toMap(SaleRecord::getProductId,Function.identity(),(existing, replacement) -> new SaleRecord(existing.getProductId(),existing.getQuantity() + replacement.getQuantity(),existing.getAmount() + replacement.getAmount())));saleRecordMap.forEach((id, record) -> System.out.println("productId: " + id + ", record: " + record));}}
在這個(gè)例子中,合并函數(shù)創(chuàng)建了一個(gè)新的SaleRecord對(duì)象,將重復(fù)鍵的商品數(shù)量和銷(xiāo)售金額進(jìn)行了累加。運(yùn)行代碼后,我們可以看到 Map 中對(duì)應(yīng)商品 id 的記錄是合并后的結(jié)果,包含了該商品的總銷(xiāo)售數(shù)量和總銷(xiāo)售金額 。如果是字符串類(lèi)型的值,也可以進(jìn)行拼接操作。比如有一個(gè)包含用戶(hù)興趣愛(ài)好的 List,每個(gè)用戶(hù)對(duì)象包含 id 和興趣愛(ài)好字段,當(dāng)轉(zhuǎn)換為 Map 時(shí),若有相同 id 的用戶(hù),將他們的興趣愛(ài)好拼接起來(lái),用逗號(hào)分隔。代碼如下:
import java.util.*;import java.util.stream.Collectors;class UserHobby {private Integer id;private String hobby;public UserHobby(Integer id, String hobby) {this.id = id;this.hobby = hobby;}public Integer getId() {return id;}public String getHobby() {return hobby;}@Overridepublic String toString() {return "UserHobby{" +"id=" + id +", hobby='" + hobby + '\'' +'}';}}public class ListToMapMergeStringExample {public static void main(String[] args) {List<UserHobby> userHobbyList = new ArrayList<>();userHobbyList.add(new UserHobby(1, "Reading"));userHobbyList.add(new UserHobby(1, "Swimming")); // 重復(fù)的idMap<Integer, String> hobbyMap = userHobbyList.stream().collect(Collectors.toMap(UserHobby::getId,UserHobby::getHobby,(existing, replacement) -> existing + ", " + replacement));hobbyMap.forEach((id, hobby) -> System.out.println("id: " + id + ", hobby: " + hobby));}}
在這個(gè)代碼中,合并函數(shù)將重復(fù) id 的用戶(hù)興趣愛(ài)好進(jìn)行了拼接,中間用逗號(hào)分隔,最終得到了一個(gè)包含每個(gè)用戶(hù)所有興趣愛(ài)好的 Map 。通過(guò)這些自定義合并策略,我們能夠根據(jù)具體的業(yè)務(wù)需求,靈活、有效地處理 List 轉(zhuǎn)換為 Map 時(shí)遇到的重復(fù)鍵值問(wèn)題,讓我們的代碼更加健壯和智能。
四、綜合實(shí)戰(zhàn)演練
圖片
(一)復(fù)雜數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換
在實(shí)際應(yīng)用中,我們面對(duì)的數(shù)據(jù)結(jié)構(gòu)往往更加復(fù)雜。接下來(lái),通過(guò)一個(gè)復(fù)雜的數(shù)據(jù)結(jié)構(gòu)示例,展示如何將其轉(zhuǎn)換為 Map 并處理重復(fù)鍵值。假設(shè)我們有一個(gè)電商系統(tǒng),其中包含訂單信息。每個(gè)訂單包含訂單 id、客戶(hù)信息、訂單明細(xì)列表,而訂單明細(xì)又包含商品信息、商品數(shù)量和商品單價(jià)?,F(xiàn)在我們要將一個(gè)包含多個(gè)訂單的 List 轉(zhuǎn)換為以訂單 id 為鍵,訂單總金額為值的 Map,并且要處理可能出現(xiàn)的重復(fù)訂單 id(雖然在實(shí)際業(yè)務(wù)中訂單 id 通常是唯一的,但為了演示處理重復(fù)鍵值的情況,這里假設(shè)存在這種可能性)。代碼如下:
import java.util.*;import java.util.stream.Collectors;// 商品類(lèi)class Product {private String productName;private double unitPrice;public Product(String productName, double unitPrice) {this.productName = productName;this.unitPrice = unitPrice;}public String getProductName() {return productName;}public double getUnitPrice() {return unitPrice;}}// 訂單明細(xì)類(lèi)class OrderItem {private Product product;private int quantity;public OrderItem(Product product, int quantity) {this.product = product;this.quantity = quantity;}public Product getProduct() {return product;}public int getQuantity() {return quantity;}// 計(jì)算訂單明細(xì)的金額public double calculateAmount() {return product.getUnitPrice() * quantity;}}// 客戶(hù)類(lèi)class Customer {private String customerName;private String contactNumber;public Customer(String customerName, String contactNumber) {this.customerName = customerName;this.contactNumber = contactNumber;}public String getCustomerName() {return customerName;}public String getContactNumber() {return contactNumber;}}// 訂單類(lèi)class Order {private int orderId;private Customer customer;private List<OrderItem> orderItems;public Order(int orderId, Customer customer, List<OrderItem> orderItems) {this.orderId = orderId;this.customer = customer;this.orderItems = orderItems;}public int getOrderId() {return orderId;}public Customer getCustomer() {return customer;}public List<OrderItem> getOrderItems() {return orderItems;}// 計(jì)算訂單總金額public double calculateTotalAmount() {return orderItems.stream().mapToDouble(OrderItem::calculateAmount).sum();}}public class ComplexListToMapExample {public static void main(String[] args) {// 創(chuàng)建商品對(duì)象Product product1 = new Product("Laptop", 1000.0);Product product2 = new Product("Mouse", 50.0);// 創(chuàng)建訂單明細(xì)對(duì)象OrderItem orderItem1 = new OrderItem(product1, 2);OrderItem orderItem2 = new OrderItem(product2, 3);// 創(chuàng)建客戶(hù)對(duì)象Customer customer1 = new Customer("Alice", "123456789");// 創(chuàng)建訂單對(duì)象Order order1 = new Order(1, customer1, Arrays.asList(orderItem1, orderItem2));Order order2 = new Order(1, customer1, Arrays.asList(orderItem1)); // 重復(fù)的訂單idList<Order> orderList = new ArrayList<>();orderList.add(order1);orderList.add(order2);// 使用Stream API將List轉(zhuǎn)換為Map,并處理重復(fù)鍵值(這里選擇合并訂單總金額)Map<Integer, Double> orderTotalAmountMap = orderList.stream().collect(Collectors.toMap(Order::getOrderId,Order::calculateTotalAmount,(existingAmount, newAmount) -> existingAmount + newAmount));orderTotalAmountMap.forEach((orderId, totalAmount) -> System.out.println("orderId: " + orderId + ", totalAmount: " + totalAmount));}}
在上述代碼中,首先定義了多個(gè)類(lèi)來(lái)表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu),包括Product(商品)、OrderItem(訂單明細(xì))、Customer(客戶(hù))和Order(訂單)。然后創(chuàng)建了一些示例數(shù)據(jù),并將其存儲(chǔ)在orderList中。最后,使用 Stream API 將orderList轉(zhuǎn)換為以訂單 id 為鍵,訂單總金額為值的 Map。在轉(zhuǎn)換過(guò)程中,通過(guò)自定義合并函數(shù)(existingAmount, newAmount) -> existingAmount + newAmount來(lái)處理可能出現(xiàn)的重復(fù)訂單 id,將重復(fù)訂單的總金額進(jìn)行合并。
(二)結(jié)合其他 Stream 操作
在將 List 轉(zhuǎn)換為 Map 的過(guò)程中,我們還可以結(jié)合其他 Stream 操作,實(shí)現(xiàn)更強(qiáng)大的數(shù)據(jù)處理功能。比如,在上述訂單的例子中,我們可以先對(duì)訂單列表進(jìn)行過(guò)濾,只選擇特定客戶(hù)的訂單,然后再進(jìn)行轉(zhuǎn)換。同時(shí),還可以對(duì)訂單明細(xì)進(jìn)行映射,提取出商品名稱(chēng),再進(jìn)行后續(xù)處理。代碼如下:
import java.util.*;import java.util.stream.Collectors;// 商品類(lèi)class Product {private String productName;private double unitPrice;public Product(String productName, double unitPrice) {this.productName = productName;this.unitPrice = unitPrice;}public String getProductName() {return productName;}public double getUnitPrice() {return unitPrice;}}// 訂單明細(xì)類(lèi)class OrderItem {private Product product;private int quantity;public OrderItem(Product product, int quantity) {this.product = product;this.quantity = quantity;}public Product getProduct() {return product;}public int getQuantity() {return quantity;}// 計(jì)算訂單明細(xì)的金額public double calculateAmount() {return product.getUnitPrice() * quantity;}}// 客戶(hù)類(lèi)class Customer {private String customerName;private String contactNumber;public Customer(String customerName, String contactNumber) {this.customerName = customerName;this.contactNumber = contactNumber;}public String getCustomerName() {return customerName;}public String getContactNumber() {return contactNumber;}}// 訂單類(lèi)class Order {private int orderId;private Customer customer;private List<OrderItem> orderItems;public Order(int orderId, Customer customer, List<OrderItem> orderItems) {this.orderId = orderId;this.customer = customer;this.orderItems = orderItems;}public int getOrderId() {return orderId;}public Customer getCustomer() {return customer;}public List<OrderItem> getOrderItems() {return orderItems;}// 計(jì)算訂單總金額public double calculateTotalAmount() {return orderItems.stream().mapToDouble(OrderItem::calculateAmount).sum();}}public class ComplexListToMapWithOtherStreamOpsExample {public static void main(String[] args) {// 創(chuàng)建商品對(duì)象Product product1 = new Product("Laptop", 1000.0);Product product2 = new Product("Mouse", 50.0);// 創(chuàng)建訂單明細(xì)對(duì)象OrderItem orderItem1 = new OrderItem(product1, 2);OrderItem orderItem2 = new OrderItem(product2, 3);// 創(chuàng)建客戶(hù)對(duì)象Customer customer1 = new Customer("Alice", "123456789");Customer customer2 = new Customer("Bob", "987654321");// 創(chuàng)建訂單對(duì)象Order order1 = new Order(1, customer1, Arrays.asList(orderItem1, orderItem2));Order order2 = new Order(2, customer2, Arrays.asList(orderItem1));List<Order> orderList = new ArrayList<>();orderList.add(order1);orderList.add(order2);// 結(jié)合過(guò)濾和映射操作,將特定客戶(hù)(這里是Alice)的訂單轉(zhuǎn)換為以訂單id為鍵,包含訂單中所有商品名稱(chēng)的List為值的MapMap<Integer, List<String>> orderProductNamesMap = orderList.stream().filter(order -> "Alice".equals(order.getCustomer().getCustomerName())).collect(Collectors.toMap(Order::getOrderId,order -> order.getOrderItems().stream().map(orderItem -> orderItem.getProduct().getProductName()).collect(Collectors.toList())));orderProductNamesMap.forEach((orderId, productNames) -> {System.out.println("orderId: " + orderId);System.out.println("Product Names: " + productNames);});}}
在這段代碼中,首先使用filter操作篩選出客戶(hù)名為 “Alice” 的訂單,然后在Collectors.toMap的第二個(gè)參數(shù)中,使用map操作提取每個(gè)訂單中所有訂單明細(xì)的商品名稱(chēng),并通過(guò)collect(Collectors.toList())將這些商品名稱(chēng)收集到一個(gè) List 中,最終得到一個(gè)以訂單 id 為鍵,包含訂單中所有商品名稱(chēng)的 List 為值的 Map。通過(guò)這樣的方式,我們可以靈活地組合各種 Stream 操作,滿(mǎn)足復(fù)雜的數(shù)據(jù)處理需求,讓 Java Stream API 在實(shí)際應(yīng)用中發(fā)揮出更大的威力。
五、總結(jié)與展望
圖片
在 Java 編程的廣闊世界里,將 List 轉(zhuǎn)換為 Map 是一項(xiàng)極為常見(jiàn)且基礎(chǔ)的操作,而 Java Stream API 的出現(xiàn),為這一操作注入了新的活力,使其變得更加簡(jiǎn)潔高效。通過(guò)使用Collectors.toMap()方法,我們能夠輕松地實(shí)現(xiàn) List 到 Map 的轉(zhuǎn)換,滿(mǎn)足各種業(yè)務(wù)場(chǎng)景的需求。
在處理重復(fù)鍵值這一關(guān)鍵問(wèn)題時(shí),我們有多種策略可供選擇。拋出異常策略能幫助我們及時(shí)發(fā)現(xiàn)數(shù)據(jù)中的潛在問(wèn)題,確保數(shù)據(jù)的準(zhǔn)確性和一致性;而自定義合并策略則賦予了我們更大的靈活性,根據(jù)不同的業(yè)務(wù)邏輯,我們可以選擇保留舊值、選擇新值或者合并值,讓代碼更加貼合實(shí)際業(yè)務(wù)需求。
通過(guò)復(fù)雜數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換和結(jié)合其他 Stream 操作的實(shí)戰(zhàn)演練,我們更加深入地領(lǐng)略了 Stream API 的強(qiáng)大功能和無(wú)限潛力。它不僅能處理簡(jiǎn)單的數(shù)據(jù)轉(zhuǎn)換,還能在復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和多樣化的業(yè)務(wù)邏輯中發(fā)揮重要作用,結(jié)合其他 Stream 操作,如過(guò)濾、映射等,Stream API 能夠?qū)崿F(xiàn)更加復(fù)雜的數(shù)據(jù)處理任務(wù),為我們的開(kāi)發(fā)工作提供了極大的便利 。
希望大家在今后的 Java 開(kāi)發(fā)中,能夠大膽地運(yùn)用 Stream API 來(lái)處理 List 到 Map 的轉(zhuǎn)換以及重復(fù)鍵值的問(wèn)題。不斷探索 Stream API 的更多用法和技巧,將其融入到日常的項(xiàng)目開(kāi)發(fā)中,相信它一定會(huì)為你的代碼帶來(lái)更高的效率和更好的可讀性,讓你的開(kāi)發(fā)工作事半功倍!