开发环境:jdk 1.8
需求一:
1、统计每个小时(升序)不同事件的产品产量
2、统计不同事件(OK 、NG)的总产量
public static void main(String[] args) {
//数据源
List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("hour", "10");//小时
map1.put("event", "OK");//事件
map1.put("number", 12);//产量
list.add(map1);
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("hour", "08");
map2.put("event", "NG");
map2.put("number", 10);
list.add(map2);
Map<String, Object> map3 = new HashMap<String, Object>();
map3.put("hour", "09");
map3.put("event", "NG");
map3.put("number", 7);
list.add(map3);
Map<String, Object> map4 = new HashMap<String, Object>();
map4.put("hour", "08");
map4.put("event", "OK");
map4.put("number", 30);
list.add(map4);
System.out.println(list);
System.out.println("--------------------------");
// 进行分组和汇总 并 按hour字段的升序排序
// 按小时统计每个小时的事件和数量
Map<String, Map<String, Integer>> hourEventNumberSum = list.stream()
.collect(Collectors.groupingBy(
item -> (String) item.get("hour"),
TreeMap::new, // 使用 TreeMap 以保证 hour 字段升序
Collectors.groupingBy(
item -> (String) item.get("event"),
Collectors.summingInt(item -> (Integer) item.get("number"))
)
));
// 打印结果
// 这里如果直接定义int变量累加计算总和,会报错:Local variable count defined in an enclosing scope must be final or effectively final,增强for里面用外部变量需要final,但这里在做累加计算,无法使用final修饰,所以改用了List<Integer>计算总和
//计算OK总和用的集合
List<Integer> listOk = new ArrayList<Integer>();
//计算NG总和用的集合
List<Integer> listNg = new ArrayList<Integer>();
hourEventNumberSum.forEach((hour, eventMap) -> {
System.out.println("Hour: " + hour);
eventMap.forEach((event, number) -> {
System.out.println(" Event: " + event + ", Number: " + number);
if ("OK".equals(event.toUpperCase())) {
listOk.add(number);
}else if ("NG".equals(event.toUpperCase())) {
listNg.add(number);
}
});
});
System.out.println("--------------------------");
//计算OK总和
int sumOk = listOk.stream()
.mapToInt(Integer::intValue) // 转换成 IntStream
.sum(); // 计算和
System.out.println("OK Sum of elements: " + sumOk);
//计算NG总和
int sumNg = listNg.stream()
.mapToInt(Integer::intValue) // 转换成 IntStream
.sum(); // 计算和
System.out.println("NG Sum of elements: " + sumNg);
}
执行结果
需求二:
统计每个小时(倒序)不同事件的产品产量
public static void main29(String[] args) {
//数据源
List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("hour", "10");
map1.put("event", "B");
map1.put("number", 12);
list.add(map1);
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("hour", "08");
map2.put("event", "A");
map2.put("number", 10);
list.add(map2);
Map<String, Object> map3 = new HashMap<String, Object>();
map3.put("hour", "09");
map3.put("event", "A");
map3.put("number", 7);
list.add(map3);
Map<String, Object> map4 = new HashMap<String, Object>();
map4.put("hour", "08");
map4.put("event", "B");
map4.put("number", 30);
list.add(map4);
System.out.println(list);
System.out.println("--------------------------");
// 进行分组和汇总
Map<String, Map<String, Integer>> hourEventNumberSum = list.stream()
.collect(Collectors.groupingBy(
item -> (String) item.get("hour"),
TreeMap::new, // 使用 TreeMap 以保证按 hour 字段升序
Collectors.groupingBy(
item -> (String) item.get("event"),
Collectors.summingInt(item -> (Integer) item.get("number"))
)
));
// 将 TreeMap 转换为倒序的 LinkedHashMap
Map<String, Map<String, Integer>> sortedHourEventNumberSum = hourEventNumberSum.entrySet()
.stream()
.sorted(Map.Entry.<String, Map<String, Integer>>comparingByKey(Comparator.reverseOrder()))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
// 打印结果
sortedHourEventNumberSum.forEach((hour, eventMap) -> {
System.out.println("Hour: " + hour);
eventMap.forEach((event, number) -> {
System.out.println(" Event: " + event + ", Number: " + number);
});
});
}