我有一个包含以下格式的数据的JSON文件:
{
"type":"type1",
"value":"value1",
"param": "param1"
}
{
"type":"type2",
"value":"value2",
"param": "param2"
}
我也有这样一个对象:
public class TestObject {
private final String value;
private final String param;
public TestObject(String value, String param) {
this.value = value;
this.param = param;
}
}
我想要的是创建一个Map<String, List<TestObject>>
,其中包含每种类型的TestObject
列表。
这就是我编码的内容:
Map<String, List<TestObject>> result = jsonFileStream
.map(this::buildTestObject)
.collect(Collectors.groupingBy(line -> JsonPath.read(line, "$.type")));
方法buildTestObject
是:
private TestObject buildTestObject(String line) {
return new TestObject(
JsonPath.read(line, "$.value"),
JsonPath.read(line, "$.param"));
}
这不起作用,因为map()
函数返回TestObject
,因此collect
函数不再适用于JSON String行。
在现实生活中,我无法添加&#34;类型&#34;变量到TestObject
文件,因为它是来自外部库的文件。
如何按JSON文件中的类型对TestObject
进行分组?
答案 0 :(得分:4)
您可以将映射操作移动到groupingBy的下游收集器:
Map<String, List<TestObject>> result = jsonFileStream
.collect(Collectors.groupingBy(line -> JsonPath.read(line, "$.type"),
Collectors.mapping(this::buildTestObject, Collectors.toList())));
这将保留字符串,以便您可以将类型提取为分类器,并将映射应用于结果组的元素。
答案 1 :(得分:1)
您还可以使用toMap
收集器来完成手头的任务。
Map<String, List<TestObject>> resultSet = jsonFileStream
.collect(Collectors.toMap(line -> JsonPath.read(line, "$.type"),
line -> new ArrayList<>(Collections.singletonList(buildTestObject(line))),
(left, right) -> {
left.addAll(right);
return left;
}
));
答案 2 :(得分:0)
除了Stream解决方案之外,值得指出的是Java 8还显着改进了Map
接口,制作了这种东西
使用for
循环实现的痛苦比之前的情况要少得多。我不熟悉您正在使用的库,但是这样的内容可以使用(您始终可以将Stream
转换为Iterable
)。
Map<String, List<TestObject>> map = new HashMap<>();
for (String line : lines) {
map.computeIfAbsent(JsonPath.read(line, "$.type"), k -> new ArrayList<>())
.add(buildTestObject(line));
}