[英]Java 8 Stream Create an Object from Map of Objects
我剛開始通過Java 8流API學習和實現集合。 我有一堂課:
public class Discount {
int amount;
String lastMarketingRegion;
Discount (int amount, String lastMarketingRegion) {
this.amount = amount;
this.lastMarketingRegion= lastMarketingRegion;
}
public int getAmount() { return amount; }
public String getLastMarketingRegion() { return lastMarketingRegion; }
public String toString() {
return String.format("{%s,\"%s\"}", amount, lastMarketingRegion);
}
}
我得到以下內容:
Map<String, Discount> prepaid = new HashMap<String, Discount>();
prepaid.put("HAPPY50", new Discount(100, "M1"));
prepaid.put("LUCKY10", new Discount(10, "M2"));
prepaid.put("FIRSTPAY", new Discount(20, "M3"));
Map<String, Discount> otherBills = new HashMap<String, Discount>();
otherBills.put("HAPPY50", new Discount(60, "M4"));
otherBills.put("LUCKY10", new Discount(7, "M5"));
otherBills.put("GOOD", new Discount(20, "M6"));
List<Map<String, Discount>> discList = new ArrayList<Map<String, Discount>>();
discList.add(prepaid);
discList.add(otherBills);
因此,基本上,我有一個針對不同付款方式的所有折扣代碼的Discount
圖列表。
要求是使用sum_of_amount
和last_region
創建所有付款類型的所有折扣代碼的單個地圖:
Map<String, Discount> totalDiscounts =
{LUCKY10={17, "M5"}, FIRSTPAY={20, "M3"}, HAPPY50={160, "M4"}, GOOD={20, "M6"}}
我可以得到:
Map<String, Integer> totalDiscounts =
{LUCKY10=17, FIRSTPAY=20, HAPPY50=160, GOOD=20}
通過使用以下代碼:
Map<String, Integer> afterFormatting = discList.stream()
.flatMap(m -> m.entrySet().stream())
.collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.summingInt(map -> map.getValue().amount)));
但該區域也需要一個Discount
對象。
我需要一個Discount對象的集合,其中的金額是相同鍵的總金額,而區域則來自otherBills。
任何幫助將非常感激。 謝謝。
來自評論
當您為LUCKY10擁有“ M2”和“ M5”條目時,為什么會期望“ LUCKY10”-“ M5”?
因為其他賬單比預付費有更高的優先級
您可以為此使用Collectors.toMap
。 它的最后一個參數是mergeFunction
,它合並兩個在地圖中具有相同String鍵的Discounts。
Map<String, Discount> totalDiscounts = discList.stream()
.flatMap(m -> m.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(discount1, discount2) -> new Discount(discount1.getAmount() + discount2.getAmount(),
discount2.getLastMarketingRegion())));
由於出列表生成的數據流是有序的,在discount2
折扣會從一個otherBills
映射,所以我選擇它的區域。
如果您通過添加otherBills
和prepaid
構造列表,那么它將具有不同的輸出。
依靠相遇順序使這不是一個很好的解決方案 。 (如果您假設我們在處理完第一個地圖后處理了第二個地圖中的條目,為什么要首先合並它們?)
查看我使用Map.merge
其他答案
如果只有兩個地圖,則可以使用Map.merge
,而不是使用基於流的解決方案(我的其他答案 )。
在這里,我們制作了prepaid
地圖的副本。 然后,我們遍歷otherBills
地圖。 對於每個鍵
Discount
對象,其金額為地圖中已存在的Discount對象(一個來自prepaid
)和當前Discount對象(一個來自otherBill
)的otherBill
。 它從otherBill
映射中獲取Discount對象的區域。 Map<String, Discount> result = new HashMap<>(prepaid);
otherBills.forEach((k, v) -> result.merge(k, v, (discountFromPrepaid, discountFromOtherBill) ->
new Discount(discountFromPrepaid.getAmount() + discountFromOtherBill.getAmount(),
discountFromOtherBill.getLastMarketingRegion())));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.