gpt4 book ai didi

java - 在Java8中使用过滤器和映射提取数据库列数据

转载 作者:行者123 更新时间:2023-11-30 01:42:27 26 4
gpt4 key购买 nike

关于员工的表包含以下数据:员工 ID、员工姓名、经理 ID 和团队成员 ID。每个员工根据其团队规模可以有多个条目。假设团队中有 5 名其他成员的员工将有 5 行,其中员工和经理 ID 与一名团队成员的 ID 重复。

示例表:

employeeId | employeeName | managerId | teamEmployeeId |
-------------------------------------------------------
1000 | Alex | 4000 | 1101 |
1200 | Bran | 4100 | 1301 |
1200 | Bran | 4100 | 1302 |
1000 | Alex | 4000 | 1102 |
1200 | Bran | 4100 | 1303 |
1000 | Alex | 4000 | 1103 |
1200 | Bran | 4100 | 1304 |
1200 | Bran | 4100 | 1305 |
1000 | Alex | 4000 | 1104 |

目标是将每个员工的团队 ID(也包括经理 ID)拆分到一个单独的数组中以供稍后使用。

预期结果:

allIds:
1000
1200

teamIds for "Alex" :
1101
1102
1103
1104
4000

teamIds for "Bran" :
1301
1302
1303
1304
1305
4100

获取唯一员工 ID 的第一部分正在工作(基于此 answer )。但是尝试使用员工 ID 拆分团队成员会返回第一个值,但次数正确。假设:一个有 5 人的团队返回一个由 5 人组成的数组,其中第一个成员的 ID 全部为 5。未添加经理 ID。

我正在使用的代码:

List<ViewData> list = getDataList();

String[] allIds = list.parallelStream()
.map(ViewData::getId).distinct().toArray(String[]::new);

System.out.println(allIds.length + "\n");

for (String id : allIds) {

String[] teamIds = list.parallelStream()
.filter(row -> row.getId().equals(id))
.map(ViewData::getTeamId).distinct()
.toArray(String[]::new);

teamIds = Arrays.copyOf(teamIds, teamIds.length+1 );
teamIds[teamIds.length] = list.parallelStream()
.filter(obj -> obj.getId().equals(id))
.map(ViewData::getManagerId).toString();
System.out.println(teamIds.length + "\n");
}

我知道这是一个逻辑错误。我引用的所有关于 filter() 的文档都显示语法是正确的。我的理解是,filter() 返回其 id 与我正在循环的行匹配的整行,而 map() 从该行中取出团队成员的 id,最后所有内容都作为字符串数组返回。

我哪里出错了?编写代码或了解这些函数如何工作?

<小时/>

编辑:

if a table like this causes duplicates/repeat rows(particularly the exact number of time it is supposed to be present):

没有主键的 View (即不保证唯一的列)需要通过组合两个唯一的列而派生出复合主键。

  • 为复合按键组合创建单独的@Embeddable

  • 将其添加到主模型类中:@EmbeddedId private UniqueId uniqueId;

  • 按照答案中的现有逻辑继续:

for (String id : allIds) {
String[] teamIds = list.stream()
.filter(row -> row.getUniqueId().getId().equals(id))
.map(obj -> obj.getUniqueId().getTeamEmployeeId())
.toArray(String[]::new);

teamIds = Arrays.copyOf(teamIds, teamIds.length + 1);
teamIds[teamIds.length - 1] = list.stream()
.filter(obj -> obj.getUniqueId().getId().equals(id))
.map(ViewData::getManagerId).findFirst().orElse("");

String empName = list.stream()
.filter(obj -> obj.getUniqueId().getId().equals(id))
.map(ViewData::getName).findFirst().orElse("");
}
<小时/>

更新:

由于对数据结构的理解有限,这是一个非常复杂的解决方案。使用 Set 的自动重复数据删除功能的更简单(稍微冗余)的解决方案:

Map<Integer, Set<Integer>> res = new HashMap<>();
employeeDetails.forEach(o-> {
Integer empId = o.empId;
if(!res.containsKey(empId)) res.put(empId, new HashSet<>());
res.get(empId).addAll(Set.of(o.teamMemberId, o.managerId));
});
return res;

即使这也不是一个非常理想的解决方案。它对 res 映射及其值进行了大量访问和修改。但与之前的方法相比,这种方法只遍历记录列表一次。两种解决方案的一些基本基准测试表明,新方法对于 1000 大小的记录速度快 3-4 倍,对于 100 秒大小的记录速度快 10 倍。

但是超过 5000 个会使两者更接近,因为它们都因创建用于存储结果的对象数量及其访问而陷入困境。

最佳答案

根据问题和评论,您需要的是:

for (String id : allIds) {
String[] teamIds = list.parallelStream()
.filter(row -> row.getId().equals(id))
.map(ViewData::getTeamId).distinct()
.toArray(String[]::new);

teamIds = Arrays.copyOf(teamIds, teamIds.length + 1);
teamIds[teamIds.length - 1] = list.parallelStream()
.filter(obj -> obj.getId().equals(id))
.map(ViewData::getManagerId)
.findFirst()
.orElse(null);

System.out.println(teamIds.length + "\n");
}

关于java - 在Java8中使用过滤器和映射提取数据库列数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59483996/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com