我有一个字符串:
String modulesToUpdate = "potato:module1, tomato:module2";
我只想从中获取:
module1
module2
首先我必须用“,”然后用“:”
拆分它所以,我这样做了:
String files[] = modulesToUpdate.split(",");
for(String file: files){
String f[] = file.split(":");
for(int i=0; i<f.length; i++){
System.out.println(f[1])
}
}
这样可行,但循环中的循环并不优雅。
我正在尝试用流做同样的事情。
所以,我这样做了:
Stream.of(modulesToUpdate)
.map(line -> line.split(","))
.flatMap(Arrays::stream)
.flatMap(Pattern.compile(":")::splitAsStream)
.forEach(f-> System.out.println(f.toString().trim()));
输出:
potato
module1
tomato
module2
如何减少/过滤它只获取:
module1
module2
答案 0 :(得分:7)
更改一行:
.map(x -> x.split(":")[1])
而不是:
.flatMap(Pattern.compile(":")::splitAsStream)
或者@Holger在评论中提到:
.map(s -> s.substring(s.indexOf(':')+1))
这根本不会创建中间数组。
flatMap
返回Stream
而Streams没有索引,但在这种情况下你确实需要它们来获取第二个令牌。
答案 1 :(得分:4)
split
操作可以立即执行所有步骤。
考虑使用分隔符模式,\s*
而不是,
进行拆分,以消除后续trim
操作的需要。同样,我们可以将不需要的前缀(匹配[^:]*?:
)视为分隔符的一部分,以将其删除。
只剩下一件事;第一个元素的前缀不被视为分隔符。我们可以做任何一种,在流操作之前手动删除它
Pattern.compile(",\\s*[^:]*?:")
.splitAsStream(modulesToUpdate.substring(modulesToUpdate.indexOf(':')+1))
.forEach(System.out::println);
或者我们允许字符串开头的前缀被视为分隔符,它允许分割操作处理它,但在开头创建一个空字符串,我们必须跳过
Pattern.compile("(^|,\\s*)[^:]*?:").splitAsStream(modulesToUpdate)
.skip(1)
.forEach(System.out::println);
答案 2 :(得分:3)
您可以在skip
内使用flatMap
,例如:
String modulesToUpdate = "potato:module1, tomato:module2";
Arrays.stream(modulesToUpdate.split(","))
.map(String::trim)
.flatMap(s -> Arrays.stream(s.split(":")).skip(1))
.forEach(System.out::println);
答案 3 :(得分:1)
也许另一种选择可以是:
String modulesToUpdate = "potato:module1, tomato:module2";
String[] mod = modulesToUpdate.split("[:,]");
List<String> res = IntStream.range(0, mod.length)
.filter(j -> (j % 2) == 0)
.mapToObj(i -> mod[i])
.collect(Collectors.toList());
System.out.println(res);