var in = List.of("A", "Q3", "Q", "Z2", "B2", "C2", "B4");
Map<String, Integer> values =
in.stream().collect(Collectors.toMap(
s -> s.substring(0, 1),
s -> s.length() == 1 ? 1 : Integer.parseInt(s.substring(1)),
(a, b) -> a + b,
() -> new TreeMap<>()));
System.out.println(values);
> {A=1, B=6, C=2, Q=4, Z=2}
一块一块的:
in.stream() - 我们想使用流API来修改列表的内容
.collect - 我们要获取数据;无需转换或过滤这些项目中的任何一个,我们希望将其全部收集到新的数据类型中
toMap - 具体来说,一个 Map,它将某些键(例如 B)映射到某个值(例如 6)。
然后我们传递 4 个参数。
- Arg 1,“keyMapper”:
s -> s.substring(0, 1)
这表示:要获得键(映射 B 中的“B”映射到 6),获取任何输入字符串,并将其缩减为第一个字符。
- Arg 2,'valueMapper':
s -> s.length == 1 ? 1 : Integer.parseInt(s.substring(1))
这就是说:要获取值,首先检查字符串的长度是否只有1,在这种情况下,值为1。否则,去掉第一个字符,然后将其余字符解析为数字
- Arg3,“合并”函数:
(a, b) -> a + b。
要合并任意 2 个值(例如来自 "Q3" 的 3 和来自 "Q" 的 1),请添加它们。
- Arg4:地图供应商:
() -> new TreeMap<>()
我们都希望将其放入 TreeMap 类型的新地图中; TreeMaps 保持自己在键上自动排序。这意味着“A=1”对首先出现在地图中,然后是 B,然后是 C,等等。 <> 告诉 java 自动找出这个映射应该有哪些键和值(字符串到整数,由于 keyMapper 和 valueMapper 函数而自动派生)。
如果您对此不熟悉,arg -> code; 的意思是:这是一个接受指定参数然后运行代码的函数。它关闭该功能(不运行它;取决于您将此功能交给的代码来运行它)。 () 是“无参数”。
如果您想获取生成的地图并生成确切的字符串...
String r = map.entrySet().stream()
.map(x -> x.getKey() + " = " + x.getValue() + ", ")
.collect(Collectors.joining());
System.out.println(r);
> A = 1, B = 6, C = 2, Q = 4, Z = 2,
虽然我不确定你为什么要这样做。
.map() 将 foos 流变成条形图,这里我们说:获取一个映射条目(例如,.getKey() 为您提供"B" 和.getValue() 为您提供6 的对象),然后将其转通过运行代码"B" + " = " + 6 + ", " 变成一个字符串,从而生成"B = 6, "。
.collect(Collectors.joining()) 的意思是:将这个字符串流按顺序连接成一个字符串。