Java8的Stream&Lambda笔记

持续更新中…

1.Stream

1.1. 过滤器

1.2. map的key不存在则创建并赋值、分组统计:

        Map<String, List<String>> map = new HashMap<>();
        map.computeIfAbsent("1", key -> new ArrayList<String>()).add("1");
        List<String> list = map.get("1");
        System.out.println(list);
//        list.stream(Collectors.groupingBy("1"), Collectors.averagingInt());

1.3. lambda

  1. 前置条件:必须是函数式接口

  2. 参数的传递:a. 可以忽略参数类型 b. 一个参数时,可以忽略括号

  3. 代码编写方式:a. 单行 b. 代码块

  4. 方法引用:

    a. 静态方法引用:

    run(SimpleLambda::doFormat);

    b. 普通方法引用:

    run(new SimpleLambda().doFormat2);

2. Stream执行机制

2.1.

在这里插入图片描述

  1. 中间节点:跟进Stream的源码后,方法若返回Stream及其子类则是!
  2. 终值节点:与1.相反!

2.2. 流的生成与不可重复使用

// 生成
list.stream();
Arrays.stream(new int[]{
    
    1,2});
Stream.of(1,2);
// 不可重复使用
Stream<String> stream1 = list.stream();
        Stream<String> stream2 = stream1.filter(k -> "1".equals(k));
        Stream<String> stream3 = stream1.filter(k -> "1".equals(k));
// 执行报错:
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed

2.3. 采集

  1. list或set

  2. map

  3. group by

  4. 数组

  5. 求最值

  6. 求任意值

3. 实际应用

public Result CommandDispatchStatistics() {
    
    
        Map<String, Object> response = new HashMap<>();
        List<Client> allValidClient = clientService.getAllValidClient();
        List<User> allValidUser = userService.getAllValidUser();
        List<Map<String, Object>> allRegion = regionService.getAllRegion4CommandDispatch();
        response.put(CommandDispatchConstant.PERSONNEL_PROJECT, getProjectAndPersonnelStatistics(allValidClient, allValidUser));
        response.put(CommandDispatchConstant.PERSONNEL_CHANGES, getPersonnelChanges(allValidClient, allValidUser));
        response.put(CommandDispatchConstant.SECOND_LINE_PERSONNEL_SITUATION, getSecondLinePersonnelSituation(allValidClient, allValidUser));
        response.put(CommandDispatchConstant.PROJECT_INFO, getProjectInfo(allValidClient, allValidUser, allRegion));
        return new Result(response);
    }

    /**
     * 获取项目及人员统计结果
     *
     * @return
     */
    private Map<String, Object> getProjectAndPersonnelStatistics(List<Client> allValidClient, List<User> allValidUser) {
    
    
        // 一线客户id集
        List<String> firstLineClientIds = allValidClient.stream().filter(c -> c.getIsSecondLine() == 0).map(c -> c.getId()).collect(Collectors.toList());
        // 二线客户id集
        List<String> secondLineClientIds = allValidClient.stream().filter(c -> c.getIsSecondLine() == 1).map(c -> c.getId()).collect(Collectors.toList());
        // 一线人员集
        List<User> firstLinePersonnelList = allValidUser.stream().filter(u -> firstLineClientIds.contains(u.getClientId())).collect(Collectors.toList());
        // 二线人员集
        List<User> secondLinePersonnelList = allValidUser.stream().filter(u -> secondLineClientIds.contains(u.getClientId())).collect(Collectors.toList());
        int firstLinePersonnelCount = firstLinePersonnelList.size();
        long currentlyOnDutyCount = firstLinePersonnelList.stream().filter(u -> u.getOnDutyStatus() == 0).count();
        int secondLinePersonnelCount = secondLinePersonnelList.size();
        // 统计结果
        Map<String, Object> statistics = new HashMap<>();
        statistics.put(CommandDispatchConstant.PROJECT_TOTAL, allValidClient.stream().filter(c -> c.getIsSecondLine() == 0).count());
        statistics.put(CommandDispatchConstant.FIRST_LINE_PERSONNEL, firstLinePersonnelCount);
        statistics.put(CommandDispatchConstant.CURRENTLY_ON_DUTY, currentlyOnDutyCount);
        statistics.put(CommandDispatchConstant.SECOND_LINE_PERSONNEL, secondLinePersonnelCount);
        return statistics;
    }

    /**
     * 获取人员变动统计结果
     *
     * @param allValidClient
     * @param allValidUser
     * @return
     */
    private Map<String, Object> getPersonnelChanges(List<Client> allValidClient, List<User> allValidUser) {
    
    
        // 一线客户集
        List<Client> firstLineClients = allValidClient.stream().filter(c -> c.getIsSecondLine() == 0).collect(Collectors.toList());
        Map<String, String> firstLineClientIdAndName = firstLineClients.stream().collect(Collectors.toMap(Client::getId, Client::getName));
        // 一线客户id集
        List<String> firstLineClientIds = firstLineClients.stream().map(c -> c.getId()).collect(Collectors.toList());
        // 一线人员集
        List<User> firstLinePersonnel = allValidUser.stream().filter(u -> firstLineClientIds.contains(u.getClientId())).collect(Collectors.toList());
        // 以客户id分组的一线入场人员
        Map<String, Long> firstLineAdmissionPersonnel = firstLinePersonnel.stream().filter(u -> u.getAdmissionStatus() == 0).collect(Collectors.groupingBy(User::getClientId, Collectors.counting()));
        // 一线投入人员
        Map<String, Integer> firstLineInputPersonnel = firstLineClients.stream().collect(Collectors.toMap(Client::getId, Client::getInputPersonnel));
        // 计算入场率
        Map<String, Object> admissionPersonnel;
        Long admissionCount;
        List<Map<String, Object>> admissionPersonnelList = new ArrayList<>();
        for (Entry<String, Integer> entry : firstLineInputPersonnel.entrySet()) {
    
    
            admissionPersonnel = new HashMap<>();
            admissionPersonnel.put(CommandDispatchConstant.NAME, firstLineClientIdAndName.get(entry.getKey()));
            admissionCount = firstLineAdmissionPersonnel.get(entry.getKey());
            admissionCount = admissionCount == null ? 0 : admissionCount;
            int inputCount = firstLineInputPersonnel.get(entry.getKey());
            admissionPersonnel.put(CommandDispatchConstant.ADMISSION_PERSONNEL, admissionCount.intValue());
            admissionPersonnel.put(CommandDispatchConstant.INPUT_PERSONNEL, inputCount);
            admissionPersonnelList.add(admissionPersonnel);
        }
        // 计算总人员入场数
        int admissionSum = admissionPersonnelList.stream().mapToInt(r -> (int) r.get(CommandDispatchConstant.ADMISSION_PERSONNEL)).sum();
        int inputSum = admissionPersonnelList.stream().mapToInt(r -> (int) r.get(CommandDispatchConstant.INPUT_PERSONNEL)).sum();
        Map<String, Object> personnelChanges = new HashMap<>();
        personnelChanges.put(CommandDispatchConstant.NAME, CommandDispatchConstant.PERSONNEL_ADMISSION_RATE);
        personnelChanges.put(CommandDispatchConstant.ADMISSION_PERSONNEL, admissionSum);
        personnelChanges.put(CommandDispatchConstant.INPUT_PERSONNEL, inputSum);
        personnelChanges.put(CommandDispatchConstant.CHILDREN, admissionPersonnelList);
        return personnelChanges;
    }

    /**
     * 二线人员情况统计
     *
     * @param allValidClient
     * @param allValidUser
     * @return
     */
    private List<Map<String, Object>> getSecondLinePersonnelSituation(List<Client> allValidClient, List<User> allValidUser) {
    
    
        // 二线客户id集
        List<String> secondLineClientIds = allValidClient.stream().filter(c -> c.getIsSecondLine() == 1).map(c -> c.getId()).collect(Collectors.toList());
        // 二线人员集
        List<User> secondLinePersonnelList = allValidUser.stream().filter(u -> secondLineClientIds.contains(u.getClientId())).collect(Collectors.toList());
        // 根据角色分组的二线人员
        Map<String, Long> secondLinePersonnelGroupByRole = secondLinePersonnelList.stream().collect(Collectors.groupingBy(User::getRole, Collectors.counting()));
        Map<String, Object> secondLinePersonnelRole;
        List<Map<String, Object>> secondLinePersonnelRoleList = new ArrayList<>();
        for (Entry<String, Long> entry : secondLinePersonnelGroupByRole.entrySet()) {
    
    
            secondLinePersonnelRole = new HashMap<>();
            secondLinePersonnelRole.put(CommandDispatchConstant.NAME, entry.getKey());
            secondLinePersonnelRole.put(CommandDispatchConstant.VALUE, entry.getValue());
            secondLinePersonnelRoleList.add(secondLinePersonnelRole);
        }
        return secondLinePersonnelRoleList;
    }

    /**
     * 项目信息统计
     *
     * @param allValidClient
     * @param allValidUser
     * @param allRegion
     * @return
     */
    private List<Map<String, Object>> getProjectInfo(List<Client> allValidClient, List<User> allValidUser, List<Map<String, Object>> allRegion) {
    
    
        // 地级市id及其上级的省份/直辖市一级的地区名称
        Map<String, String> allRegionIdAndParentName = allRegion.stream().collect(Collectors.toMap(m -> m.get(CommandDispatchConstant.ID).toString(), m -> m.get(CommandDispatchConstant.PARENT_NAME).toString()));
        // 一线客户集
        List<Client> firstLineClients = allValidClient.stream().filter(c -> c.getIsSecondLine() == 0).collect(Collectors.toList());
        Map<String, String> firstLineClientIdAndAreaId = firstLineClients.stream().collect(Collectors.toMap(Client::getId, Client::getAreaId));
        // 一线客户id集
        List<String> firstLineClientIds = firstLineClients.stream().map(c -> c.getId()).collect(Collectors.toList());
        // 一线人员集
        List<User> firstLinePersonnel = allValidUser.stream().filter(u -> firstLineClientIds.contains(u.getClientId())).collect(Collectors.toList());
        // 按地区分组并统计总客户数
        Map<String, Long> clientSumGroupByAreaId = firstLineClients.stream().collect(Collectors.groupingBy(Client::getAreaId, Collectors.counting()));
        // 按地区分组并统计投入人员总数
        Map<String, Integer> inputSumGroupByAreaId = firstLineClients.stream().collect(Collectors.groupingBy(Client::getAreaId, Collectors.summingInt(Client::getInputPersonnel)));
        // 按客户id分组并统计当前在岗总数
        Map<String, Long> onDutySumGroupByClientId = firstLinePersonnel.stream().filter(u -> u.getOnDutyStatus() == 0).collect(Collectors.groupingBy(User::getClientId, Collectors.counting()));
        // 按地区id分组并统计当前在岗总数
        Map<String, AtomicInteger> onDutySumGroupByAreaId = new HashMap<>();
        String clientId, areaId;
        AtomicInteger onDutySum;
        for (Entry<String, Long> onDutySumGroupByClientIdEntry : onDutySumGroupByClientId.entrySet()) {
    
    
            clientId = onDutySumGroupByClientIdEntry.getKey();
            areaId = firstLineClientIdAndAreaId.get(clientId);
            onDutySum = onDutySumGroupByAreaId.putIfAbsent(areaId, new AtomicInteger(onDutySumGroupByClientIdEntry.getValue().intValue()));
            if (onDutySum != null) {
    
    
                onDutySum.getAndAdd(onDutySumGroupByClientIdEntry.getValue().intValue());
            }
        }
        // 按照地区和类型分组的客户
        Map<String, Map<Integer, List<Client>>> firstLineClientGroupByAreaIdAndType = firstLineClients.stream().collect(Collectors.groupingBy(Client::getAreaId, Collectors.groupingBy(Client::getType)));
        // 汇总统计结果
        List<Map<String, Object>> projectInfoList = new ArrayList<>();
        Map<String, Object> projectInfo, allClientInfo, perClientInfo;
        List<Map<String, Object>> allClientInfoList, perTypeOfClientInfoList;
        List<Client> perTypeOfClientList;
        for (Entry<String, Long> clientSumGroupByAreaIdEntry : clientSumGroupByAreaId.entrySet()) {
    
    
            projectInfo = new HashMap<>();
            areaId = clientSumGroupByAreaIdEntry.getKey();
            projectInfo.put(CommandDispatchConstant.NAME, allRegionIdAndParentName.get(areaId));
            int clientTotal = clientSumGroupByAreaIdEntry.getValue().intValue();
            projectInfo.put(CommandDispatchConstant.CLIENT_TOTAL, clientTotal);
            if (clientTotal == 1) {
    
    
                // 一个客户时显示客户名
                perTypeOfClientList = firstLineClientGroupByAreaIdAndType.get(areaId).values().stream().collect(Collectors.toList()).get(0);
                projectInfo.put(CommandDispatchConstant.CLIENT, perTypeOfClientList.get(0).getName());
            } else {
    
    
                projectInfo.put(CommandDispatchConstant.CLIENT, "客户(" + clientTotal + ")");
            }
            projectInfo.put(CommandDispatchConstant.INPUT_TOTAL, inputSumGroupByAreaId.get(areaId));
            projectInfo.put(CommandDispatchConstant.ON_DUTY_TOTAL, onDutySumGroupByAreaId.get(areaId) == null ? 0 : onDutySumGroupByAreaId.get(areaId));
            projectInfo.put(CommandDispatchConstant.CHILDREN, new ArrayList<>());
            // 一级children:所有客户类型的客户集合
            allClientInfoList = (List<Map<String, Object>>) projectInfo.get(CommandDispatchConstant.CHILDREN);
            for (Entry<Integer, List<Client>> typeAndClientEntry : firstLineClientGroupByAreaIdAndType.get(areaId).entrySet()) {
    
    
                int type = typeAndClientEntry.getKey();
                perTypeOfClientList = typeAndClientEntry.getValue();
                allClientInfo = new HashMap<>();
                allClientInfo.put(CommandDispatchConstant.CLIENT_TYPE, type);
                allClientInfo.put(CommandDispatchConstant.CHILDREN, new ArrayList<>());
                // 二级children:每种客户类型的客户集合
                perTypeOfClientInfoList = (List<Map<String, Object>>) allClientInfo.get(CommandDispatchConstant.CHILDREN);
                for (Client client : perTypeOfClientList) {
    
    
                    perClientInfo = new HashMap<>();
                    perClientInfo.put(CommandDispatchConstant.NAME, client.getName());
                    perClientInfo.put(CommandDispatchConstant.INPUT_PERSONNEL, client.getInputPersonnel());
                    perClientInfo.put(CommandDispatchConstant.ON_DUTY_PERSONNEL, onDutySumGroupByClientId.get(client.getId()) == null ? 0 : onDutySumGroupByClientId.get(client.getId()));
                    perTypeOfClientInfoList.add(perClientInfo);
                }
                allClientInfoList.add(allClientInfo);
            }
            projectInfoList.add(projectInfo);
        }
        return projectInfoList;
    }

参考:
1.https://mp.weixin.qq.com/s/84TSGjui1pT4cL1o8vNsTw

2.https://blog.csdn.net/u011207553/article/details/80285386

3.https://www.cnblogs.com/caiguangbi-53/p/12504826.html

4.https://segmentfault.com/q/1010000011573553/a-1020000011588217

5.深入理解Java Stream流水线

6.JAVA8 中 关于Map 新增 computeIfAbsent 方法的使用

猜你喜欢

转载自blog.csdn.net/weixin_41085114/article/details/107886876