Abh*_*ava 4 java string lambda java-8 java-stream
我有一串字符串 -
Token1:Token2:Token3
这':'是分隔字符.这里Token3String可以包含分隔符或者可以不存在.我们有这个流转换为地图TOKEN1为键和值是二strings-的阵列array[0] = Token2和array[1] = Token3是否Token3存在其他,null.我尝试过类似的东西 -
return Arrays.stream(inputArray)
.map( elem -> elem.split(":"))
.filter( elem -> elem.length==2 )
.collect(Collectors.toMap( e-> e[0], e -> {e[1],e[2]}));
Run Code Online (Sandbox Code Playgroud)
但它没有用.如果Token3不存在或者包含分隔符,它就不会处理这种情况.
如何在Java8 lambda表达式中完成它?
您可以将每个输入字符串映射到正则表达式Matcher,然后只保留那些实际匹配并通过toMap收集器使用Matcher.group()方法收集的字符串:
Map<String, String[]> map = Arrays.stream(inputArray)
.map(Pattern.compile("([^:]++):([^:]++):?(.+)?")::matcher)
.filter(Matcher::matches)
.collect(Collectors.toMap(m -> m.group(1), m -> new String[] {m.group(2), m.group(3)}));
Run Code Online (Sandbox Code Playgroud)
全面测试:
String[] inputArray = {"Token1:Token2:Token3:other",
"foo:bar:baz:qux", "test:test"};
Map<String, String[]> map = Arrays.stream(inputArray)
.map(Pattern.compile("([^:]++):([^:]++):?(.+)?")::matcher)
.filter(Matcher::matches)
.collect(Collectors.toMap(m -> m.group(1), m -> new String[] {m.group(2), m.group(3)}));
map.forEach((k, v) -> {
System.out.println(k+" => "+Arrays.toString(v));
});
Run Code Online (Sandbox Code Playgroud)
输出:
test => [test, null]
foo => [bar, baz:qux]
Token1 => [Token2, Token3:other]
Run Code Online (Sandbox Code Playgroud)
同样的问题也可以解决String.split.您只需要使用两个arg拆分版本并指定您最多需要多少部分:
Map<String, String[]> map = Arrays.stream(inputArray)
.map(elem -> elem.split(":", 3)) // 3 means that no more than 3 parts are necessary
.filter(elem -> elem.length >= 2)
.collect(Collectors.toMap(m -> m[0],
m -> new String[] {m[1], m.length > 2 ? m[2] : null}));
Run Code Online (Sandbox Code Playgroud)
结果是一样的.
| 归档时间: |
|
| 查看次数: |
2770 次 |
| 最近记录: |