【Java】Stream流复杂分组及排序使用

  • Post author:
  • Post category:java


数据模拟

	// 模拟一些数据,假设这些是1班2班部分同学的数学成绩列表,然后需要进行按班级分组
	List<Map<String, Object>> list = new ArrayList<>();
	Map<String, Object> map1 = new HashMap<>();
	map1.put("name","张三");
 	map1.put("class",1);
    map1.put("score",50);
    list.add(map1);
    Map<String, Object> map2 = new HashMap<>();
	map2.put("name","李四");
 	map2.put("class",2);
    map2.put("score",40);
    list.add(map2 );
    Map<String, Object> map3 = new HashMap<>();
	map3.put("name","王五");
 	map3.put("class",2);
    map3.put("score",60);
    list.add(map1);
    Map<String, Object> map4 = new HashMap<>();
	map4.put("name","赵六");
 	map4.put("class",1);
    map4.put("score",30);
    list.add(map4);

一、分组

1.分组

根据map对象中的一个key的值来对list进行分组,如根据班级class进行分组:

	// 根据class来对list进行分组:
	Map<Integer, List<Map<String, Object>>> classMap = list
	.stream().collect(Collectors.groupingBy(map -> (int) map.get("class")));

此时classMap的key便是原来list中每个map的class的值,而value则是每个class的值相同的mapList集合.

2.分组求和

根据map对象中的一个key的值来对list进行分组并求和,如根据班级分完组后分别求各个班级所有同学的分数和,即:

	// 根据class来对list进行分组并求取score和
	Map<Integer, Integer> sumMap = list.stream()
	.collect(Collectors.groupingBy(map -> (int) map.get("class"), Collectors.summingInt(map -> (int) map.get("score"))));
	//  根据class来对list进行分组并求取条数
	Map<Integer, Long> countMap = list.stream()
    .collect(Collectors.groupingBy(map -> (int) map.get("class"), Collectors.counting()));

3.分组取最大最小值

根据map对象中的一个key的值来对list进行分组并求取最大值,如根据班级class来对list进行分组并求取每个班分数的最大值

	// 根据class来对list进行分组并求取最大值
	Map<Integer, Optional<Map<String, Object>>> maxBy = list
	.stream().collect(Collectors.groupingBy(map -> (int) map.get("class"), Collectors.maxBy(Comparator.comparingInt(map -> (int) map.get("score")))));
	// 获取
	int classNo = 1;
	Map<String, Object> mapMap = maxBy.get(classNo).get();

最小值同理,只需要吧maxBy改成minBy

4.分组数据统计(包括最大最小及求和)

	// 假如我们需要取出1班的分数数据进行统计
	int classNo = 1;
	Map<Integer, IntSummaryStatistics> collect = list.stream()
	.collect(Collectors.groupingBy(map -> (int) map.get("class"), Collectors.summarizingInt(item -> (int) item.get("score"))));
	IntSummaryStatistics intSummaryStatistics = collect.get(classNo);
	// 求分数平均值
	double average = intSummaryStatistics.getAverage();
	// 求条数
	long count = intSummaryStatistics.getCount();
	// 分数最大值
	int max = intSummaryStatistics.getMax();
	// 分数最小值
	int min = intSummaryStatistics.getMin();
	// 分数和
	long sum = intSummaryStatistics.getSum();

二、排序

1.单一排序

根据分数score进行排序:

	// 根据分数score进行排序(默认升序):
	List<Map<String, Object>> scoreSortList = list
	.stream().sorted(Comparator.comparing(map -> (int) map.get("score"))).collect(Collectors.toList());
	// 根据分数score进行降序排列:
	List<Map<String, Object>> reScoreSortList = list
	.sorted(Comparator.comparing(map -> (int) map.get("score"),Comparator.reverseOrder())).collect(Collectors.toList());

2.多条件排序

先根据班级class正序排再根据分数score降序排:

	// 先根据班级class正序排再根据分数score降序排:
	List<Map<String, Object>> ortList = list
	.stream().sorted(Comparator.comparing(map -> {
			Map<String, Object> tempMap = (Map<String, Object>) map;
            return (int)tempMap.get("class");
    }).thenComparing(map -> {
            Map<String, Object> tempMap = (Map<String, Object>) map;
            return (int)tempMap.get("score");
    },Comparator.reverseOrder())).collect(Collectors.toList());        


待续…


版权声明:本文为cottonknight原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。