java8 GroupingBy 用法大全

本文展示了Java8中Collectors.groupingBy方法在处理数据时的多种用法,包括按水果名称分组、统计种类数量、计算总数量、找出数量最大项、收集价格、创建数量与价格的映射关系以及计算平均数量。示例代码详细演示了如何使用这些功能对商品数据进行操作。
摘要由CSDN通过智能技术生成

  java8中,Collectors.groupingBy 会用得比较多,对其常见用法做一个汇总

1,模拟数据

Item

import java.math.BigDecimal;

public class Item {
    private String name;
    private Integer quantity;
    private BigDecimal price;

    public Item(String name, int quantity, BigDecimal price) {
        this.name = name;
        this.quantity  = quantity;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getQuantity() {
        return quantity;
    }

    public void setQuantity(Integer quantity) {
        this.quantity = quantity;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}

数据

public static List<Item> initData(){
        List<Item> items = Arrays.asList(new Item("apple", 20, new BigDecimal("4.99")),
                new Item("apple", 30, new BigDecimal("7.99")),
                new Item("apple", 10, new BigDecimal("9.99")),
                new Item("banana", 30, new BigDecimal("2.99")),
                new Item("banana", 20, new BigDecimal("6.99")),
                new Item("orange", 50, new BigDecimal("3.99")),
                new Item("orange", 20, new BigDecimal("8.99")),
                new Item("watermelon", 200, new BigDecimal("2.99")),
                new Item("watermelon", 100, new BigDecimal("5.99")),
                new Item("kiwi fruit", 40, new BigDecimal("5.88")),
                new Item("kiwi fruit", 20, new BigDecimal("8.88")));
        return items;
    }

2,用法

1,groupingBy

     // 根据水果名称分组
    private static void groupingBy(){
        List<Item> items = initData();
        Map<String, List<Item>> itemGroupBy = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName));
        System.out.println(JSON.toJSONString(itemGroupBy));
    }

结果:


{
	"orange": [{
		"name": "orange",
		"price": 3.99,
		"quantity": 50
	}, {
		"name": "orange",
		"price": 8.99,
		"quantity": 20
	}],
	"banana": [{
		"name": "banana",
		"price": 2.99,
		"quantity": 30
	}, {
		"name": "banana",
		"price": 6.99,
		"quantity": 20
	}],
	"apple": [{
		"name": "apple",
		"price": 4.99,
		"quantity": 20
	}, {
		"name": "apple",
		"price": 7.99,
		"quantity": 30
	}, {
		"name": "apple",
		"price": 9.99,
		"quantity": 10
	}],
	"kiwi fruit": [{
		"name": "kiwi fruit",
		"price": 5.88,
		"quantity": 40
	}, {
		"name": "kiwi fruit",
		"price": 8.88,
		"quantity": 20
	}],
	"watermelon": [{
		"name": "watermelon",
		"price": 2.99,
		"quantity": 200
	}, {
		"name": "watermelon",
		"price": 5.99,
		"quantity": 100
	}]
}

2,groupingCounting

    // 统计水果的种类
    private static void groupingCounting(){
        List<Item> items = initData();
        Map<String, Long> itemGroupCount = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName, Collectors.counting()));
        System.out.println(JSON.toJSONString(itemGroupCount));
    }

结果

{
	"orange": 2,
	"banana": 2,
	"apple": 3,
	"kiwi fruit": 2,
	"watermelon": 2
}

3,groupingSum

    // 统计各水果的总数量
    private static void groupingSum(){
        List<Item> items = initData();
        Map<String, Integer> itemGroupSum = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName, 
Collectors.summingInt(Item::getQuantity)));
        System.out.println(JSON.toJSONString(itemGroupSum));
    }

结果

{
	"orange": 70,
	"banana": 50,
	"apple": 60,
	"kiwi fruit": 60,
	"watermelon": 300
}

 4,groupingMax

     // 统计各水果中数量最多的那个
    private static void groupingMax(){
        List<Item> items = initData();
        Map<String, Item> itemGroupMax = ListUtils.emptyIfNull(items).stream()
                .collect(Collectors.groupingBy(Item::getName,
                Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingInt(Item::getQuantity)), Optional::get)));
        System.out.println(JSON.toJSONString(itemGroupMax));
        Map<String, Item> itemGroupMaxMap = ListUtils.emptyIfNull(items).stream()
                .collect(Collectors.toMap(Item::getName, Function.identity(), 
                        BinaryOperator.maxBy(Comparator.comparingInt(Item::getQuantity))));
        System.out.println(JSON.toJSONString(itemGroupMaxMap));
    }

 结果

{
	"orange": {
		"name": "orange",
		"price": 3.99,
		"quantity": 50
	},
	"banana": {
		"name": "banana",
		"price": 2.99,
		"quantity": 30
	},
	"apple": {
		"name": "apple",
		"price": 7.99,
		"quantity": 30
	},
	"kiwi fruit": {
		"name": "kiwi fruit",
		"price": 5.88,
		"quantity": 40
	},
	"watermelon": {
		"name": "watermelon",
		"price": 2.99,
		"quantity": 200
	}
}

Collectors.collectingAndThen 聚合后再操作

其参数:

collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher) 

 5,grouping mapping

     // 统计各水果的价格
    private static void groupingSet(){
        List<Item> items = initData();
        Map<String, Set<BigDecimal>> itemGroupSet = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName,
                Collectors.mapping(Item::getPrice, Collectors.toSet())));
        System.out.println(JSON.toJSONString(itemGroupSet));

        Map<String, List<BigDecimal>> itemGroupList = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName,
                Collectors.mapping(Item::getPrice, Collectors.toList())));
        System.out.println(JSON.toJSONString(itemGroupList));
    }

 结果

{
	"orange": [3.99, 8.99],
	"banana": [2.99, 6.99],
	"apple": [7.99, 9.99, 4.99],
	"kiwi fruit": [5.88, 8.88],
	"watermelon": [2.99, 5.99]
}

  6,groupingMap

    // 统计各水果的数量对应价格
    private static void groupingMap(){
        List<Item> items = initData();
        Map<String, Map<Integer, BigDecimal>> itemGroupMap = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName,
                Collectors.toMap(Item::getQuantity, Item::getPrice, (x, y) -> x)));
        System.out.println(JSON.toJSONString(itemGroupMap));

        Map<String, Map<Integer, BigDecimal>> itemGroupMap2 = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName, Collectors
                .collectingAndThen(Collectors.toMap(Item::getQuantity, Item::getPrice), v -> v)));
        System.out.println(JSON.toJSONString(itemGroupMap2));
    }

  结果

{
	"orange": {
		50: 3.99,
		20: 8.99
	},
	"banana": {
		20: 6.99,
		30: 2.99
	},
	"apple": {
		20: 4.99,
		10: 9.99,
		30: 7.99
	},
	"kiwi fruit": {
		20: 8.88,
		40: 5.88
	},
	"watermelon": {
		100: 5.99,
		200: 2.99
	}
}

第一种更为简便

 7,groupingAvg

    // 统计各水果的平均数量  int double long 三种类型
    private static void groupingAvg(){
        List<Item> items = initData();
        Map<String, Double> itemGroupAvg = ListUtils.emptyIfNull(items).stream()
                .collect(Collectors.groupingBy(Item::getName,
 Collectors.averagingInt(Item::getQuantity)));
        System.out.println(JSON.toJSONString(itemGroupAvg));
    }

  结果

{
	"orange": 35.0,
	"banana": 25.0,
	"apple": 20.0,
	"kiwi fruit": 30.0,
	"watermelon": 150.0
}

总结:

   常见使用聚合再进行map处理,用于匹配数据。了解Collectors.collectingAndThen的用法,聚合后再进行操作。写不来,就分两步写,先完成,再优化。

Java 8的groupingBy是一个用于对集合进行分组的方法。它是Stream API中的一个终端操作,可以基于给定的分类函数将元素分组成一个Map。 下面是groupingBy方法的基本语法: ``` public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier) ``` 其中,T表示集合中的元素的类型,K表示分组的键的类型。classifier是一个函数,用于根据元素生成分组的键。 下面是一个示例,演示如何使用groupingBy对一个字符串集合进行分组,按照字符串的长度进行分组: ```java List<String> strings = Arrays.asList("apple", "banana", "cat", "dog", "elephant", "fish"); Map<Integer, List<String>> result = strings.stream() .collect(Collectors.groupingBy(String::length)); System.out.println(result); ``` 运行结果为: ``` {3=[cat, dog], 4=[fish], 5=[apple], 6=[banana], 8=[elephant]} ``` 在这个例子中,我们使用String::length作为分类函数,将字符串按照长度分组成一个Map,其中键是字符串的长度,值是具有相同长度的字符串列表。 除了上述示例,groupingBy还可以与其他收集器一起使用,实现更复杂的分组操作。例如,我们可以使用groupingBy结合counting收集器来统计每个分组中元素的数量: ```java Map<Integer, Long> result = strings.stream() .collect(Collectors.groupingBy(String::length, Collectors.counting())); System.out.println(result); ``` 运行结果为: ``` {3=2, 4=1, 5=1, 6=1, 8=1} ``` 这个例子中,我们使用groupingBy和counting收集器结合,统计每个分组中元素的数量。 总结:Java 8的groupingBy方法是一个强大的工具,可以帮助我们对集合进行灵活的分组操作。它通过分类函数将元素分组成一个Map,可以与其他收集器一起使用,实现更复杂的分组统计等操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天狼1222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值