如何解决如何以最有效的方式迭代 List 并为其设置数据?
我正在处理一个问题,我需要迭代一个大小为 N 的数组列表并与另一个列表进行比较,对于所有匹配的元素,我需要在其上设置一些数据。下面给出了示例和我迄今为止尝试过的内容。
List<Emp> emp= new ArrayList<>();
List<Student> stud = new ArrayList<>();
class Emp -> int id,String status,String name;
class Student -> int id,String studStatus,String name;
如果学生和员工的 id 匹配,则使用一些默认值更新 emp 状态。
到目前为止,我尝试了这段代码,但它并没有帮助我获得所需的结果。纠正我在这里做错了什么?
stud.stream().filter(i -> emp.stream().filter(j ->
j.getId().equals(i.getId()))
.map(i -> i.setStatus(Status.PASS)));
解决方法
A map
是一个中间操作。除非您附加终端操作,否则不会调用流管道。
为避免二次时间复杂度,请通过构造 Map<Integer,Emp>
进行预处理。
Map<Integer,Emp> empData = emp.stream()
.collect(Collectors.toMap(Emp::getId,Function.identity()));
如果有多个 Emp
对象具有相同的 Id
,这将引发异常。
接下来,遍历学生并从上面的地图中获取适当的 Emp
实例并更改状态
stud.stream()
.filter(student -> empData.containsKey(student.getId()))
.forEach(student -> empData.get(student.getId()).setStatus(Status.PASS));
,
最简单的方法是首先像这样创建一组所有学生 ID:
package.json
通过使用 Set<Integer> studentIds = stud.stream()
.map(Student::getId)
.collect(Collectors.toSet());
而不是 Set
,我们还可以避免重复 ID。
现在我们可以遍历员工并查看员工 ID 是否包含在学生 ID 集中。如果是,我们会更新员工的状态。
List
,
流并不比 for 循环更有效,因此请使用:
int studSize = stud.size();
int empSize = emp.size();
for(int i=0; i<studSize; i++) {
for(int j=0; j<empSize; j++) {
if (stud.get(i).getId() == emp.get(j).getId) {
stud.setStatus(Status.PASS);
break;
}
}
}
,
在您的代码中需要注意以下几点:
- .filter 应该返回一个布尔值,以便它过滤记录。但在你的情况下,这并没有发生。您应该对内部过滤器输出进行计数,看看它是否大于 0。或者,简化此操作并使用 anyMatch
- .map 需要相同实体/类的响应。但是当您使用 setter 时,您将返回 void,因此您的 setter 并没有真正生效。要么使用不同的自定义 setter 返回更新的对象,要么使用代码块返回更新的对象。
- .map 不是终端操作。因此,整个表达式甚至没有被执行。您可能需要一个像收集这样的终端操作,或者甚至只是一个让轮子运动的计数
- 看起来您正在为 Status 使用枚举,但这不是类的定义方式...
如果您想保留您的代码并进行更正...下面是您可以执行的操作
stud.stream()
.filter(i -> emp.stream().filter(j -> j.getId() == i.getId()).count() > 0L) // ensure the outer filter is getting a boolean output
.map(i -> {
i.setStudStatus(Status.PASS);
return i; // unless you return,the setter does not take effect
})
.count(); // terminal operation
如果您可以使用稍微不同的方法并简化初始过滤器,并使用更好的方式终止而不是映射和计数,那么请参考以下(推荐)
stud.stream()
.filter(s -> {return emp.stream().anyMatch(e -> (e.id == s.id)); })
.forEach(s -> s.setStatus(Status.PASS));
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。