Java groupingBy 和转换字符串
Java groupingBy and transform Strings
我收到了一个字符串列表,我试图用 .groupingBy()
进行分区,这将给我一个 Map<String, List<String>>
,并转换将要在列表中结束的字符串在地图上。
Examples I've found 使用 Collectors.mapping
,这是我想使用的,但所有示例都使用方法引用,例如 .mapping(SomeClass::getSomething, ...
,因为我正在对字符串进行操作, 做不到。
我想我可以使用 lambda 作为映射函数,但似乎无法获得正确的语法,最终出现“类型不匹配:无法转换...”错误。
这说明了我正在尝试做的事情 —
import java.util.*;
import java.util.stream.Collectors;
class Main
{
public static void main(String[] args)
{
List<String> inputs = Arrays.asList("D8", "S1", "S5", "D2", "D15", "S9");
System.out.println(inputs);
Map<String, List<String>>
outputs = inputs.stream()
.collect(
Collectors.groupingBy(s -> s.startsWith("D") ? "desperate" : "serious")
//,Collectors.mapping(n -> Integer.valueOf(n.replaceAll("[DS]", "")), Collectors.toList())
)
;
System.out.println(outputs);
}
}
这将创建地图,按我的预期对输入数据进行分组,并生成输出
{desperate=[D8, D2, D15], serious=[S1, S5, S9]}
但是我想要的,正如你可能从注释掉的行中猜到的那样
Collectors.mapping(n -> Integer.valueOf(n.replaceAll("[DS]", "")), Collectors.toList())
是一个 Map<String, List<Integer>>
包含通过删除前缀从字符串中提取的值。
我的实际用例可能会将一个字符串转换为另一个字符串,或者从更复杂的字符串中提取整数,但这说明了我正在尝试做的事情。
如何在分组时使用 lambda 函数进行映射?
我也不清楚我读过的例子中 Collectors.mapping
中第二个参数 toList()
的用法。
我用这段代码创建了一个 repl。
Collectors.groupingBy()
有一个版本采用另一个收集器作为值,例如:
@Test
public void streamsTest() {
List<String> inputs = Arrays.asList("D8", "S1", "S5", "D2", "D15", "S9");
System.out.println(inputs);
Map<String, List<Integer>> outputs = inputs.stream()
.collect(
Collectors.groupingBy(
s -> s.startsWith("D") ? "desperate" : "serious",
Collectors.mapping(
s -> Integer.valueOf(s.substring(1)),
Collectors.toList())));
System.out.println(outputs);
}
这会产生:
[D8, S1, S5, D2, D15, S9]
{desperate=[8, 2, 15], serious=[1, 5, 9]}
这类似于。不同的是,转化可以发生在群体之外,可以独立进化。
流、地图、群组
- 流式传输元素
- 使用
map
转换每个元素(这可以委托给单独的函数)
- 定义收集策略
- 基于收集策略分组
- 根据需要收集元素
import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
class TransformAndGroupBy {
public static void main(String[] args) {
List<String> inputs = Arrays.asList("D8", "S1", "S5", "D2", "D15", "S9");
System.out.println(inputs);
Function<String, SimpleEntry<String, Integer>> transform = s -> s.startsWith("D")
? new SimpleEntry<>("desparate", Integer.parseInt(s.substring(1)))
: new SimpleEntry<>("serious", Integer.parseInt(s.substring(1)));
Map<String, List<Integer>> outputs = inputs.stream() // convert to stream
.map(transform) // do the necessary transformation
.collect(Collectors.groupingBy(e -> e.getKey(), Collectors.mapping(e -> e.getValue(), Collectors.toList()))); // group and collect as per the transformation
System.out.println(outputs);
}
}
我收到了一个字符串列表,我试图用 .groupingBy()
进行分区,这将给我一个 Map<String, List<String>>
,并转换将要在列表中结束的字符串在地图上。
Examples I've found 使用 Collectors.mapping
,这是我想使用的,但所有示例都使用方法引用,例如 .mapping(SomeClass::getSomething, ...
,因为我正在对字符串进行操作, 做不到。
我想我可以使用 lambda 作为映射函数,但似乎无法获得正确的语法,最终出现“类型不匹配:无法转换...”错误。
这说明了我正在尝试做的事情 —
import java.util.*;
import java.util.stream.Collectors;
class Main
{
public static void main(String[] args)
{
List<String> inputs = Arrays.asList("D8", "S1", "S5", "D2", "D15", "S9");
System.out.println(inputs);
Map<String, List<String>>
outputs = inputs.stream()
.collect(
Collectors.groupingBy(s -> s.startsWith("D") ? "desperate" : "serious")
//,Collectors.mapping(n -> Integer.valueOf(n.replaceAll("[DS]", "")), Collectors.toList())
)
;
System.out.println(outputs);
}
}
这将创建地图,按我的预期对输入数据进行分组,并生成输出
{desperate=[D8, D2, D15], serious=[S1, S5, S9]}
但是我想要的,正如你可能从注释掉的行中猜到的那样
Collectors.mapping(n -> Integer.valueOf(n.replaceAll("[DS]", "")), Collectors.toList())
是一个 Map<String, List<Integer>>
包含通过删除前缀从字符串中提取的值。
我的实际用例可能会将一个字符串转换为另一个字符串,或者从更复杂的字符串中提取整数,但这说明了我正在尝试做的事情。
如何在分组时使用 lambda 函数进行映射?
我也不清楚我读过的例子中 Collectors.mapping
中第二个参数 toList()
的用法。
我用这段代码创建了一个 repl。
Collectors.groupingBy()
有一个版本采用另一个收集器作为值,例如:
@Test
public void streamsTest() {
List<String> inputs = Arrays.asList("D8", "S1", "S5", "D2", "D15", "S9");
System.out.println(inputs);
Map<String, List<Integer>> outputs = inputs.stream()
.collect(
Collectors.groupingBy(
s -> s.startsWith("D") ? "desperate" : "serious",
Collectors.mapping(
s -> Integer.valueOf(s.substring(1)),
Collectors.toList())));
System.out.println(outputs);
}
这会产生:
[D8, S1, S5, D2, D15, S9]
{desperate=[8, 2, 15], serious=[1, 5, 9]}
这类似于
流、地图、群组
- 流式传输元素
- 使用
map
转换每个元素(这可以委托给单独的函数) - 定义收集策略
- 基于收集策略分组
- 根据需要收集元素
import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
class TransformAndGroupBy {
public static void main(String[] args) {
List<String> inputs = Arrays.asList("D8", "S1", "S5", "D2", "D15", "S9");
System.out.println(inputs);
Function<String, SimpleEntry<String, Integer>> transform = s -> s.startsWith("D")
? new SimpleEntry<>("desparate", Integer.parseInt(s.substring(1)))
: new SimpleEntry<>("serious", Integer.parseInt(s.substring(1)));
Map<String, List<Integer>> outputs = inputs.stream() // convert to stream
.map(transform) // do the necessary transformation
.collect(Collectors.groupingBy(e -> e.getKey(), Collectors.mapping(e -> e.getValue(), Collectors.toList()))); // group and collect as per the transformation
System.out.println(outputs);
}
}