Java 8 Stream 从对象映射创建对象

我刚开始通过 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 的相同键和区域的总金额。


任何帮助将不胜感激。谢谢。


白猪掌柜的
浏览 431回答 2
2回答

蓝山帝景

来自评论当您有 LUCKY10 的“M2”和“M5”条目时,为什么您期望“LUCKY10”-“M5”?因为 otherBills 比预付更优先您可以Collectors.toMap为此使用。它的最后一个参数是mergeFunction合并地图中具有相同字符串键的两个折扣。Map<String, Discount> totalDiscounts = discList.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .flatMap(m -> m.entrySet().stream())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (discount1, discount2) -> new Discount(discount1.getAmount() + discount2.getAmount(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; discount2.getLastMarketingRegion())));由于从列表中生成的流是有序的,discount2 折扣将是otherBills地图中的那个,因此我选择了它的区域。如果您通过添加otherBills后跟来构建列表prepaid,那么这将有不同的输出。依靠遭遇顺序使这不是一个很好的解决方案。(如果您假设我们在处理第一个地图后处理第二个地图中的条目,为什么首先合并它们?)

临摹微笑

如果您只有两张地图,那么与其使用基于流的解决方案,您可以使用Map.merge它。在这里,我们制作prepaid地图的副本。然后我们遍历otherBills地图。对于每个键如果映射不存在,则将其添加到映射(结果映射)中如果映射已经存在,我们构造一个新Discount对象,其数量是映射中已经存在的 Discount 对象(来自 的prepaid那个)和当前的 Discount 对象(来自 的那个)的总和otherBill。它从otherBill地图中获取 Discount 对象的区域。Map<String, Discount> result = new HashMap<>(prepaid);otherBills.forEach((k, v) -> result.merge(k, v, (discountFromPrepaid, discountFromOtherBill) ->&nbsp; &nbsp; &nbsp; &nbsp; new Discount(discountFromPrepaid.getAmount() + discountFromOtherBill.getAmount(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; discountFromOtherBill.getLastMarketingRegion())));
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java