代码如下:
public class Service{
public IPage<ChannelAgentOrgVO> getChannelAgentTeamStream(Page<ChannelAgentOrgVO> page, Channel channel) {
Page<Channel> channelPage = this.getPage(new Page<>(page.getCurrent(), page.getSize()), channel);
Stream<Channel> channelStream = channelPage.getRecords().stream();
Stream<ChannelAgentOrgVO> voStream = channelStream.map(c -> {
ChannelAgentOrgVO vo = new ChannelAgentOrgVO();
vo.setChannel(c);
return vo;
});
List<Long> channelOrgIds = channelPage.getRecords().stream().map(Channel::getChannelOrgId).collect(Collectors.toList());
List<Long> agentOrgIds = channelPage.getRecords().stream().map(Channel::getAgentOrgId).collect(Collectors.toList());
List<Long> agentTeamIds = channelPage.getRecords().stream().map(Channel::getAgentTeamId).collect(Collectors.toList());
List<ChannelOrg> channelOrgList = channelOrgService.lambdaQuery().in(ChannelOrg::getId, channelOrgIds)
.select(ChannelOrg::getId,
ChannelOrg::getCode,
ChannelOrg::getName,
ChannelOrg::getFullName,
ChannelOrg::getType)
.list();
List<Org> agentOrgList = agentOrgService.lambdaQuery().in(Org::getId, agentOrgIds)
.select(Org::getId,
Org::getCode,
Org::getName,
Org::getFullName,
Org::getType)
.list();
List<AgentTeam> agentTeamList = agentTeamService.lambdaQuery().in(AgentTeam::getId, agentTeamIds)
.select(AgentTeam::getId,
AgentTeam::getName,
AgentTeam::getFullName,
AgentTeam::getAddressDetail,
AgentTeam::getAddressName,
AgentTeam::getAddressContact)
.list();
voStream = voStream.peek(vo -> channelOrgList.forEach(channelOrg -> {
if (Objects.equals(channelOrg.getId(), vo.getChannel().getChannelOrgId())) {
vo.setChannelOrg(channelOrg);
}
}));
voStream = voStream.peek(vo -> agentOrgList.forEach(agentOrg -> {
if (Objects.equals(agentOrg.getId(), vo.getChannel().getAgentOrgId())) {
vo.setAgentOrg(agentOrg);
}
}));
voStream = voStream.map(vo -> {
agentTeamList.forEach(agentTeam -> {
if (Objects.equals(agentTeam.getId(), vo.getChannel().getAgentTeamId())) {
vo.setAgentTeam(agentTeam);
}
});
return vo;
});
return new PageResult<>(channelPage, voStream.collect(Collectors.toList())).getVoPage();
}
}
1
shanghai1943 2021-07-15 14:27:28 +08:00
为什么不把 xxOrgList 转成 Map<Long, Object> 的形式来组装数据?
|
2
ccppgo OP @shanghai1943 我很想这么做.. 但是我好像有点不开窍, 大佬能直接改我的代码让我学习下么.. 主楼已经把整个方法的代码贴出来了
|
3
xuanbg 2021-07-15 14:31:46 +08:00
你自己组装的过程还能怎么优化?只能在查询上面进行优化。
|
4
oneisall8955 2021-07-15 14:48:31 +08:00
说实话,这里的 stream 没必要,为了用 sream 而用 stream,没有解决最核心的耗时性能问题
channel,agent,agentTeam 各个 ID 集合,只需要 for 循环一次 channelPage.getRecords()就可以得到而代码用了三次 channelPage.getRecords().stream().map(Channel::getXxxId) voStream 三次 peek/map 也没必要,只需要一次 for 循环一次就可以 setChannelOrg/setAgentOrg/setAgentTeam 并且 setChannelOrg/setAgentOrg/setAgentTeam,可以先将 hannelOrgList 、agentOrgList 、agentTeamList 先转三个 map,而不是形如 cchannelOrgList.forEach 。。。if (Objects.equals(channelOrg.getId(), vo.getChannel().getChannelOrgId())。。。这种每次都遍历 list |
5
ccppgo OP @xuanbg 其实我意思是想看看各位大佬 操作 java stream 的 api 是怎么写, 有没有优化空间, 查询上面应该没问题了, 只是简单的单表查询用后用 id 关联..
|
6
ccppgo OP @oneisall8955 是的, 这其实就是我的问题所在, 我想看看怎么写这种操作, 因为不是很熟悉 Java,刚写第二周
|
7
mitsuizzz 2021-07-15 14:57:22 +08:00
可以先把 id 查出来,然后并行通过 id 去查附加信息,然后循环一次,把信息组装下
|
8
shanghai1943 2021-07-15 15:00:50 +08:00
Map<Long, ChannelOrg> map =channelOrgList.stream().collect(Collectors.toMap(ChannelOrg::geChannelOrgId,ChannelOrg->ChannelOrg));
其他两个类似转化 然后用一个 for 循环生成最终对象并且把这三个 map 根据 id 获取 value 然后 set 到最终对象里 |
9
oneisall8955 2021-07-15 15:10:15 +08:00
@ccppgo #6 list 转 map 很简单吧
``` class Foo{ int code; string name; } // list 通过 stream 转 map List<Foo> list = new ArrayList<>(); Map<Integer, Foo> map = list.stream().collect(Collectors.toMap(Foo::getCode, Function.identity(), (f1, f2) -> f1)); Foo foo = map.get(1); // 使用 Guava 库 Map<Integer, Foo> map = Maps.uniqueIndex(list,Foo::getCode); ``` |
10
ccppgo OP @shanghai1943
@mitsuizzz @oneisall8955 三位大佬, 我好像有点开悟了, 请问还有优化空间吗 [![WnF2wt.png]( https://z3.ax1x.com/2021/07/15/WnF2wt.png)]( https://imgtu.com/i/WnF2wt) |
11
shanghai1943 2021-07-15 15:17:19 +08:00
你这 voStream 里 setXXX 是不是跟下面 for 循环里做的事情重复了?
|
12
ccppgo OP #10
还有个问题, stream 和 foreach 都能做得时候, 使用 stream 好过 foreach 吗 |
13
ccppgo OP @shanghai1943 是的, 我是想知道 使用 stream 和 foreach 哪个更好
|
14
shanghai1943 2021-07-15 15:21:27 +08:00
一般比较更好的时候会参考性能,可读性,以及后续维护成本来看。站在这几个方面来看的话,你觉得哪个更好?
|
15
ccppgo OP @shanghai1943 我看过一些网上的分析, 貌似数据量少时,foreach 性能稍微高一丢丢, 数据量大时 stream 性能更高, 而且还可以用多核并行, 并且 stream 的可读性和维护性 比 foreach 要好, 我感觉比较喜欢 stream
|
16
thetbw 2021-07-16 17:22:42 +08:00
lambdaQuery 是用于哪个 orm 吗
|
18
running17 2021-07-17 11:10:30 +08:00
每次在项目里看到这种 forEach 嵌套 forEach 去筛选取值的,都会忍不住去改成 Map 的形式,一次循环可以完成事情的,虽然小数据量下效率不会有很大的提升,但是感觉思路习惯还是养成的==
|