我有一个Java lambda流,它根据一些基本过滤来解析文件并将结果存储到一个集合中.
我只是在学习lambdas,所以如果这是非常糟糕的话,请耐心等待我.但请随意指出我的错误.
对于给定的文件:
#ignored
this
is
#ignored
working
fine
Run Code Online (Sandbox Code Playgroud)
代码:
List<String> matches;
Stream<String> g = Files.lines(Paths.get(givenFile));
matches = g.filter(line -> !line.startsWith("#"))
.collect(Collectors.toList());
["this", "is", "working", "fine"]
Run Code Online (Sandbox Code Playgroud)
现在,我将如何将忽略的行收集到同一个流中的第二个列表中?就像是:
List<String> matches;
List<String> ignored; // to store lines that start with #
Stream<String> g = Files.lines(Paths.get(exclusionFile.toURI()));
matches = g.filter(line -> !line.startsWith("#"))
// how can I add a condition to throw these
// non-matching lines into the ignored collection?
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
我意识到打开一个新的流,稍微改变一下逻辑并且.collect()容易被忽略的行是非常简单的.但是,如果我可以在一个流中完成所有操作,我不想两次遍历此文件.
Sar*_*ana 13
您可以partitioningBy在收集器中使用两个流,而不是两个流
List<String> strings = Arrays.asList("#ignored", "this", "is", "#ignored", "working", "fine");
Map<Boolean, List<String>> map = strings.stream().collect(Collectors.partitioningBy(s -> s.startsWith("#")));
System.out.println(map);
Run Code Online (Sandbox Code Playgroud)
产量
{false=[this, is, working, fine], true=[#ignored, #ignored]}
Run Code Online (Sandbox Code Playgroud)
这里我使用了key,Boolean但您可以将其更改为有意义的字符串或枚举
编辑
如果字符串可以从您可以使用的其他一些特殊字符开始 groupingBy
List<String> strings = Arrays.asList("#ignored", "this", "is", "#ignored", "working", "fine", "!Someother", "*star");
Function<String, String> classifier = s -> {
if (s.matches("^[!@#$%^&*]{1}.*")) {
return Character.toString(s.charAt(0));
} else {
return "others";
}
};
Map<String, List<String>> maps = strings.stream().collect(Collectors.groupingBy(classifier));
System.out.println(maps);
Run Code Online (Sandbox Code Playgroud)
产量
{!=[!Someother], #=[#ignored, #ignored], *=[*star], others=[this, is, working, fine]}
Run Code Online (Sandbox Code Playgroud)
你也可以窝groupingBy和partitioningBy