我想知道是否可以在 Java 8 中使用java.utils.stream重写嵌套的for
循环?
这是我正在使用的示例数据类型:
class Folder {
private final String name;
private final Integer itemCound;
Folder(String name, Integer itemCount) {
this.name = name;
this.itemCount = itemCount;
}
public String getName() { return this.name; }
public Integer getItemCount() { return this.itemCount; }
}
这里的代码在起作用:
List<Folder> oldFolders = new ArrayList<>();
List<Folder> newFolders = new ArrayList<>();
// Fill folder collections with sample data...
oldFolders.add(new Folder("folder1", 2));
oldFolders.add(new Folder("folder2", 4));
newFolders.add(new Folder("folder1", 0));
newFolders.add(new Folder("folder2", 100));
// This part should be rewrited using streams
for (Folder newFolder : newFolders) {
for (Folder oldFolder : oldFolders) {
if (newFolder.getName().equals(oldFolder.getName())
&& !newFolder.getItemCount().equals(oldFolder.getItemCount())) {
// do stuff...
}
}
}
P.S:我在 SO 上看到了其他问题,但所有这些问题都有一个集合或一个具有自己的嵌套集合的集合,而不是像我的示例中的两个不同集合。
谢谢!
答案 0 :(得分:1)
是的,您可以:
newFolders.forEach((newFolder) -> {
oldFolders.forEach((oldFolder) -> {
if (newFolder.getName().equals(oldFolder.getName())
&& !newFolder.getItemCount().equals(oldFolder.getItemCount())) {
// do stuff...
}
})
})
编辑:但是正如@Kayaman在下面的评论中提到的,这不一定比仅使用嵌套的for循环更好。
当您应该或不应该考虑使用流时,这是一本不错的书:
答案 1 :(得分:1)
除非可以并行化第一个迭代(在此示例中进行了评论),否则这并没有太大的改善
List<String> oldList = new ArrayList<>();
List<String> newList = new ArrayList<>();
oldList
//.stream()
//.parallel()
.forEach(s1 ->
newList
.stream()
.filter(s2 -> s1.equals(s2)) //could become a parameter Predicate
.forEach(System.out::println) //could become a parameter Consumer
);
用if
和他的filter
代替Predicate
,然后对其执行一个方法。
这将提供一种动态解决方案,为Predicate
和Consumer
方法提供不同的filter
和forEach
。那将是进行此转换的唯一原因。
答案 2 :(得分:0)
我不知道您的doStuff
会做什么。但是像这样的事情会起作用。
Map<String, List<Folder>> oldFoldersByName = oldFolders.stream()
.collect(Collectors.groupingBy(Folder::getName));
newFolders.stream()
.filter(f -> oldFoldersByName.get(f.getName()).size() > 0 && oldFoldersByName
.get(f.getName()).stream().allMatch(of -> !of.getItemCount().equals(f.getItemCount()))).map(// do stuff...);
如果doStuff
是Function
,那么map
将起作用。如果它是Consumer
,则可以相应地使用forEach
。不幸的是,我没有自由知道这个doStuff
的作用,这对我来说只是一个黑匣子。
答案 3 :(得分:0)
尝试一下:
newFolders.stream().filter(newFolder ->
oldFolders
.stream()
.anyMatch(oldFolder->
newFolder.getName().equals(oldFolder.getName()) &&
!newFolder.getItemCount().equals(oldFolder.getItemCount())
)).forEach(folder -> {
//dostuff
});