你可以将每个输入字符串映射到正则表达式的Matcher,然后只保留实际匹配的字符串,并使用Matcher.group()方法通过toMap收集器进行收集:
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)}));
完整测试:
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));
});
输出:
test => [test, null]
foo => [bar, baz:qux]
Token1 => [Token2, Token3:other]
同样的问题也可以使用
String.split
来解决。你只需要使用带有两个参数的分割版本,并指定最多要拆分成几部分即可:
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}));
结果是相同的。
Map<String, String[]>
吗?可能现在应该是Map<String, String>
。 - Tagir Valeev