Java 8 Streams中的字符串操作

时间:2016-03-15 05:47:20

标签: java string lambda java-8 java-stream

我有一串字符串像 - Token1:Token2:Token3 这里':'是分隔符。这里Token3字符串中可能包含分隔符或可能不存在。 我们必须将此流转换为地图,并将Token1作为键,并且值为两个字符串的数组 - 如果array[0] = Token2存在则为array[1] = Token3Token3,否则为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]}));

但它没有用。如果Token3不存在或者包含分隔符,它就不会处理这种情况。

如何在Java8 lambda表达式中完成它?

2 个答案:

答案 0 :(得分:6)

您可以将每个输入字符串映射到正则表达式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)}));

完整测试:

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来解决。您只需要使用两个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}));

结果是一样的。

答案 1 :(得分:2)

您可以通过以下方式实现您想要的目标:

    return Arrays.stream(inputArray)
            .map(elem -> elem.split(":", 3)) // split into at most 3 parts
            .filter(arr -> arr.length >= 2)  // discard invalid input (?)
            .collect(Collectors.toMap(arr -> arr[0], arr -> Arrays.copyOfRange(arr, 1, 3)));  // will add null as the second element if the array length is 2