Java 使用lambda的嵌套过滤器
我正在尝试编写一个多级过滤器。我有文件夹和文件Java 使用lambda的嵌套过滤器,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,我正在尝试编写一个多级过滤器。我有文件夹和文件 public class Folder { String name; List<Folder> folders; List<File> files; ... } public class File { String name; String type; ... } 公共类文件夹{ 字符串名; 列出文件夹; 列出文件; ... } 公共类文件{ 字符串名; 字符串类型; ... } 我需要一个
public class Folder {
String name;
List<Folder> folders;
List<File> files;
...
}
public class File {
String name;
String type;
...
}
公共类文件夹{
字符串名;
列出文件夹;
列出文件;
...
}
公共类文件{
字符串名;
字符串类型;
...
}
我需要一个过滤器来查找某些属性,例如名称,可以是文件夹/文件名。我写了一段只适用于一个级别的代码,但我不知道如何通过寻找两个级别的循环来实现这一点
最终结果将是文件夹列表:名称与“名称筛选器”匹配的文件夹或文件名与筛选器匹配的文件夹
List<Folder> result = folders.stream()
.filter(folder -> folder.getFiles().stream().anyMatch(file -> file.getName().contains(filter)))
.collect(Collectors.toList());
List result=folders.stream()
.filter(文件夹->文件夹.getFiles().stream().anyMatch(文件->文件.getName().contains(过滤器)))
.collect(Collectors.toList());
我认为最好在Folder类中添加一个helper方法,该方法将嵌套文件夹以递归方式展平到流中:
class Folder {
String name;
List<Folder> folders;
List<File> files;
Stream<Folder> flatten() {
return Stream.concat(Stream.of(this), folders.stream().flatMap(Folder::flatten));
}
}
一个正在运行的测试,它通过文件夹中的文件名进行过滤(没有任何帮助器方法) 您的方法中最重要的部分就是@Ernest所指的flatMap旁边的区别,它将所有文件元素展平到一个列表中
private static final String FILE_NAME_FILTER = "1";
private static final String HOME_FOLDER_FILTER = "home";
private static final String VAR_FOLDER_FILTER = "var";
private static final String BIN_FOLDER_FILTER = "bin";
@Test
public void test() {
File f1 = new File("1", "txt");
File f2 = new File("1", "json");
File f3 = new File("1", "yml");
File f4 = new File("4", "doc");
Folder folder1 = new Folder(HOME_FOLDER_FILTER, asList(f1, f2));
Folder folder2 = new Folder(VAR_FOLDER_FILTER, asList(f2, f3));
Folder folder3 = new Folder(BIN_FOLDER_FILTER, asList(f3, f4));
List<Folder> folders = asList(folder1, folder2, folder3);
List<File> files = folders.stream()
.filter(folder -> folder.getName().equals(HOME_FOLDER_FILTER))
.map(Folder::getFiles) // no helper method
.flatMap(List::stream)
.filter(file -> file.getName().equals(FILE_NAME_FILTER))
.collect(Collectors.toList());
Assert.assertEquals(2, files.size());
}
私有静态最终字符串文件\u NAME\u FILTER=“1”;
私有静态最终字符串HOME\u FOLDER\u FILTER=“HOME”;
私有静态最终字符串VAR\u FOLDER\u FILTER=“VAR”;
私有静态最终字符串BIN\u FOLDER\u FILTER=“BIN”;
@试验
公开无效测试(){
文件f1=新文件(“1”、“txt”);
文件f2=新文件(“1”、“json”);
文件f3=新文件(“1”,“yml”);
文件f4=新文件(“4”,“文件”);
Folder folder1=新文件夹(主文件夹过滤器,asList(f1,f2));
Folder folder2=新文件夹(变量文件夹过滤器,asList(f2,f3));
Folder folder3=新文件夹(BIN_Folder_过滤器,asList(f3,f4));
列表文件夹=asList(folder1、folder2、folder3);
列表文件=文件夹.stream()
.filter(folder->folder.getName().equals(HOME\u folder\u filter))
.map(Folder::getFiles)//无帮助程序方法
.flatMap(列表::流)
.filter(文件->文件.getName().equals(文件名\u过滤器))
.collect(Collectors.toList());
Assert.assertEquals(2,files.size());
}
与@Oleksandr的建议大致相同
编辑:我发现我忽略了一个事实,一个文件夹可以包含一个文件夹。我应该删除这个答案吗?使用递归的方法可能是一个更好的主意
private static final String FILE_NAME_FILTER = "1";
private static final String HOME_FOLDER_FILTER = "home";
private static final String VAR_FOLDER_FILTER = "var";
private static final String BIN_FOLDER_FILTER = "bin";
@Test
public void test() {
File f1 = new File("1", "txt");
File f2 = new File("1", "json");
File f3 = new File("1", "yml");
File f4 = new File("4", "doc");
Folder folder1 = new Folder(HOME_FOLDER_FILTER, asList(f1, f2));
Folder folder2 = new Folder(VAR_FOLDER_FILTER, asList(f2, f3));
Folder folder3 = new Folder(BIN_FOLDER_FILTER, asList(f3, f4));
List<Folder> folders = asList(folder1, folder2, folder3);
List<File> files = folders.stream()
.filter(folder -> folder.getName().equals(HOME_FOLDER_FILTER))
.map(Folder::getFiles) // no helper method
.flatMap(List::stream)
.filter(file -> file.getName().equals(FILE_NAME_FILTER))
.collect(Collectors.toList());
Assert.assertEquals(2, files.size());
}