我try 做的一个简单示例:
假设我有一个字符串列表,如果包含或不包含特定的子字符串,则需要根据条件将其分为4组.如果一个字符串包含Foo
,它应该属于组FOO
,如果它包含Bar
,它应该属于组BAR
,如果它包含两个,它应该出现在两个组中.
List<String> strings = List.of("Foo", "FooBar", "FooBarBaz", "XXX");
由于字符串被分组到第一个匹配组中,因此上述输入的简单方法无法按预期工作:
Map<String,List<String>> result1 =
strings.stream()
.collect(Collectors.groupingBy(
str -> str.contains("Foo") ? "FOO" :
str.contains("Bar") ? "BAR" :
str.contains("Baz") ? "BAZ" : "DEFAULT"));
结果1为
{FOO=[Foo, FooBar, FooBarBaz], DEFAULT=[XXX]}
其中,预期结果应为
{FOO=[Foo, FooBar, FooBarBaz], BAR=[FooBar, FooBarBaz], BAZ=[FooBarBaz], DEFAULT=[XXX]}
在搜索了一段时间后,我找到了另一种方法,接近我想要的结果,但并不完全
Map<String,List<String>> result2 =
List.of("Foo", "Bar", "Baz", "Default").stream()
.flatMap(str -> strings.stream().filter(s -> s.contains(str)).map(s -> new String[]{str.toUpperCase(), s}))
.collect(Collectors.groupingBy(arr -> arr[0], Collectors.mapping(arr -> arr[1], Collectors.toList())));
System.out.println(result2);
结果2为
{BAR=[FooBar, FooBarBaz], FOO=[Foo, FooBar, FooBarBaz], BAZ=[FooBarBaz]}
虽然这样可以将包含子字符串的字符串正确地分组到所需的组中,但忽略不包含子字符串的字符串,因此应该属于默认组.预期结果如上所述(顺序无关紧要)
{BAR=[FooBar, FooBarBaz], FOO=[Foo, FooBar, FooBarBaz], BAZ=[FooBarBaz], DEFAULT=[XXX]}
目前,我正在使用两个结果图,并做额外的工作:
result2.put("DEFAULT", result1.get("DEFAULT"));
以上可以一步完成吗?有没有比我上面提到的更好的方法?