如何使用Java Stream获取每个商品对应的前3家规模最大的门店
按商品分组取Top N规模门店实现方案
实现思路
- 先按售卖商品对门店列表做分组,得到Key为商品名、Value为对应门店列表的Map
- 对每个分组的门店列表按规模
size降序排序 - 截取排序后列表的前N个元素,N可自定义调整,不足N个时返回全部分组门店
完整代码实现
import java.util.Comparator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Shop { int size; String item; String name; public Shop(int size, String item, String name){ this.size = size; this.item = item; this.name = name; } // 补全getter方法 public int getSize() { return size; } public String getItem() { return item; } public String getName() { return name; } public static void main(String[] args) { // 构造示例数据 List<Shop> shops = new LinkedList<>(); shops.add(new Shop(100, "Hammer", "Walmart")); shops.add(new Shop(30, "Scissor", "Target")); shops.add(new Shop(300, "Hammer", "Walgreens")); shops.add(new Shop(500, "Hammer", "Glens")); shops.add(new Shop(75, "Scissor", "Walmart")); shops.add(new Shop(150, "Hammer", "Toms")); // 自定义Top N的数量,修改该值即可扩展取前多少家 final int TOP_N = 3; // 核心逻辑:分组后取每个分组的Top N门店 Map<String, List<Shop>> topShopsByItem = shops.stream() // 按商品分组 .collect(Collectors.groupingBy(Shop::getItem)) .entrySet() .stream() .collect(Collectors.toMap( Map.Entry::getKey, // 对每个分组的门店排序后取前N个 entry -> entry.getValue().stream() .sorted(Comparator.comparingInt(Shop::getSize).reversed()) .limit(TOP_N) .collect(Collectors.toList()) )); // 遍历输出结果验证 topShopsByItem.forEach((item, shopList) -> { System.out.println("商品:" + item); shopList.forEach(shop -> System.out.printf("门店名:%s,规模:%d%n", shop.getName(), shop.getSize())); }); } }
运行结果说明
以示例数据为例,输出结果如下:
商品:Hammer 门店名:Glens,规模:500 门店名:Walgreens,规模:300 门店名:Toms,规模:150 商品:Scissor 门店名:Walmart,规模:75 门店名:Target,规模:30
如果需要调整取前多少家,只需要修改TOP_N常量的值即可。
内容的提问来源于stack exchange,提问作者Linkx_lair
相关产品推荐
相关产品推荐

