持续更新中…
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
-
前置条件:必须是函数式接口
-
参数的传递:a. 可以忽略参数类型 b. 一个参数时,可以忽略括号
-
代码编写方式:a. 单行 b. 代码块
-
方法引用:
a. 静态方法引用:
run(SimpleLambda::doFormat);
b. 普通方法引用:
run(new SimpleLambda().doFormat2);
2. Stream执行机制
2.1.
- 中间节点:跟进Stream的源码后,方法若返回Stream及其子类则是!
- 终值节点:与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. 采集
-
list或set
-
map
-
group by
-
数组
-
求最值
-
求任意值
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