使用 Java 流获取 json 键的计数
Get Count of json key using Java Stream
我有一个 json 对象,看起来像这样
[{
"startAt": 1617605301292,
"endAt": 1617605317095,
"duration": 15803,
"selection": {
"selected.Speed": "0",
"selected.Low": "65535",
"selected.Fast": "7173",
"selected.medium": "5"
},
"details": {
"phase": [{
"value": "2",
"timestamp": 1617605301316
}]
}
},
{
"startAt": 1617603849697,
"endAt": 1617603966378,
"duration": 116681,
"selection": {
"selected.Speed": "0",
"selected.Low": "65535",
"selected.Fast": "123",
"selected.medium": "5"
},
"details": {
"phase": [{
"value": "2",
"timestamp": 1617603849749
}]
}
}
]
我需要计算 selected.Fast 发生了多少次。我正在尝试使用流,这是我到目前为止所写的
List<Map<String, Object>> jsonObj = mapper.readValue(jArr, new TypeReference<List<Map<String, Object>>>(){});
Map<String, Long> counted = jsonObj.stream()
.map(x -> x.get("selection").toString() )
.collect(Collectors.toList())
.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counted.toString());
但是我正在计算选择对象中的所有键,我想计算特定的 Json 键,即 selected.Fast
例如
selected.Fast:"7173" -> occurred - 5times selected.Fast:"123" -> occurred - 2times
如有任何帮助,我们将不胜感激。
I need to count how many times selected.Fast has occurred.
这是你想要的吗?
List<Map<String, Object>> jsonObj = mapper.readValue(jArr, new TypeReference<List<Map<String, Object>>>(){});
long count = jsonObj.stream()
.map(x -> x.get("selection").toString())
.filter(s -> s.contains("selected.Fast"))
.count()
System.out.println(count);
您可以使用 jackson 库正常反序列化并创建这样的对象结构:
@Setter
@Getter
@NoArgsConstructor
static class Source {
private long startAt;
private long endAt;
private long duration;
private SourceSelection selection;
private SourceDetails details;
}
@Setter
@Getter
@NoArgsConstructor
static class SourceSelection {
private long speed;
private long low;
private long fast;
private long medium;
}
@Setter
@Getter
@NoArgsConstructor
static class SourceDetails {
private List<SourcePhase> phase;
}
@Setter
@Getter
@NoArgsConstructor
static class SourcePhase {
private int value;
private long timestamp;
}
然后您需要将 json 反序列化为 Source.class 对象:
List<Source> sourceList = new ObjectMapper().readValue(
JSON,
new ObjectMapper().getTypeFactory().constructCollectionType(List.class, Source.class)
);
当 JSON
是您的来源时 json
然后您可以使用标准流 API 进行映射、过滤和计数:
long result = sourceList.stream()
.map(Source::getSelection)
.filter(s-> s.getFast() != 0)
.count();
你能看看这是否是你要找的吗?
List<JsonNode> jsonObj = mapper.readValue(jArr, new TypeReference<List<JsonNode>>() {
});
Map<String, Long> counted = jsonObj.stream()
.map(x -> {
String selection = x.get("selection").get("selected.Fast").asText();
return "selected.Fast:" + selection;
}).collect(Collectors.toList())
.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counted); //{selected.Fast:123=1, selected.Fast:7173=1}
编辑:不转换为 JsonNode
List<Map<String, Object>> jsonObj = mapper.readValue(jArr, new TypeReference<List<Map<String, Object>>>(){});
Map<String, Long> counted = jsonObj.stream()
.map(x -> {
String selection = ((Map<String,Object>)x.get("selection")).get("selected.Fast").toString();
return "selected.Fast:" + selection;
}).collect(Collectors.toList())
.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counted);
编辑 2:计算所选内容中所有元素的数量的解决方案
Map<String, Long> counted = jsonObj.stream().flatMap(x -> {
JsonNode selection = x.get("selection");
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(selection.fields(), 0), false);
})
.map(x -> x.getKey() + ":" + x.getValue()).collect(Collectors.toList())
.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counted);
要输出层数不定的JSON记录的所有层级中指定名称的字段信息,Java代码会很长很复杂
您可以使用 open-source Java 软件包 SPL 来执行此操作。很简单,一行代码就够了:
A
1
=json(file("data.json").read()).groups(#4.#3;count(~)).("selected.Fast:\""/#1/""-> occurred -"/#2/"times")
SPL 提供 JDBC 驱动程序供 Java 调用。只需将上面的 SPL 脚本存储为 count.splx 并在调用存储过程时在 Java 中调用它:
…
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
st = con.prepareCall("call count()");
st.execute();
…
我有一个 json 对象,看起来像这样
[{
"startAt": 1617605301292,
"endAt": 1617605317095,
"duration": 15803,
"selection": {
"selected.Speed": "0",
"selected.Low": "65535",
"selected.Fast": "7173",
"selected.medium": "5"
},
"details": {
"phase": [{
"value": "2",
"timestamp": 1617605301316
}]
}
},
{
"startAt": 1617603849697,
"endAt": 1617603966378,
"duration": 116681,
"selection": {
"selected.Speed": "0",
"selected.Low": "65535",
"selected.Fast": "123",
"selected.medium": "5"
},
"details": {
"phase": [{
"value": "2",
"timestamp": 1617603849749
}]
}
}
]
我需要计算 selected.Fast 发生了多少次。我正在尝试使用流,这是我到目前为止所写的
List<Map<String, Object>> jsonObj = mapper.readValue(jArr, new TypeReference<List<Map<String, Object>>>(){});
Map<String, Long> counted = jsonObj.stream()
.map(x -> x.get("selection").toString() )
.collect(Collectors.toList())
.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counted.toString());
但是我正在计算选择对象中的所有键,我想计算特定的 Json 键,即 selected.Fast
例如
selected.Fast:"7173" -> occurred - 5times selected.Fast:"123" -> occurred - 2times
如有任何帮助,我们将不胜感激。
I need to count how many times selected.Fast has occurred.
这是你想要的吗?
List<Map<String, Object>> jsonObj = mapper.readValue(jArr, new TypeReference<List<Map<String, Object>>>(){});
long count = jsonObj.stream()
.map(x -> x.get("selection").toString())
.filter(s -> s.contains("selected.Fast"))
.count()
System.out.println(count);
您可以使用 jackson 库正常反序列化并创建这样的对象结构:
@Setter
@Getter
@NoArgsConstructor
static class Source {
private long startAt;
private long endAt;
private long duration;
private SourceSelection selection;
private SourceDetails details;
}
@Setter
@Getter
@NoArgsConstructor
static class SourceSelection {
private long speed;
private long low;
private long fast;
private long medium;
}
@Setter
@Getter
@NoArgsConstructor
static class SourceDetails {
private List<SourcePhase> phase;
}
@Setter
@Getter
@NoArgsConstructor
static class SourcePhase {
private int value;
private long timestamp;
}
然后您需要将 json 反序列化为 Source.class 对象:
List<Source> sourceList = new ObjectMapper().readValue(
JSON,
new ObjectMapper().getTypeFactory().constructCollectionType(List.class, Source.class)
);
当 JSON
是您的来源时 json
然后您可以使用标准流 API 进行映射、过滤和计数:
long result = sourceList.stream()
.map(Source::getSelection)
.filter(s-> s.getFast() != 0)
.count();
你能看看这是否是你要找的吗?
List<JsonNode> jsonObj = mapper.readValue(jArr, new TypeReference<List<JsonNode>>() {
});
Map<String, Long> counted = jsonObj.stream()
.map(x -> {
String selection = x.get("selection").get("selected.Fast").asText();
return "selected.Fast:" + selection;
}).collect(Collectors.toList())
.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counted); //{selected.Fast:123=1, selected.Fast:7173=1}
编辑:不转换为 JsonNode
List<Map<String, Object>> jsonObj = mapper.readValue(jArr, new TypeReference<List<Map<String, Object>>>(){});
Map<String, Long> counted = jsonObj.stream()
.map(x -> {
String selection = ((Map<String,Object>)x.get("selection")).get("selected.Fast").toString();
return "selected.Fast:" + selection;
}).collect(Collectors.toList())
.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counted);
编辑 2:计算所选内容中所有元素的数量的解决方案
Map<String, Long> counted = jsonObj.stream().flatMap(x -> {
JsonNode selection = x.get("selection");
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(selection.fields(), 0), false);
})
.map(x -> x.getKey() + ":" + x.getValue()).collect(Collectors.toList())
.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counted);
要输出层数不定的JSON记录的所有层级中指定名称的字段信息,Java代码会很长很复杂
您可以使用 open-source Java 软件包 SPL 来执行此操作。很简单,一行代码就够了:
A | |
---|---|
1 | =json(file("data.json").read()).groups(#4.#3;count(~)).("selected.Fast:\""/#1/""-> occurred -"/#2/"times") |
SPL 提供 JDBC 驱动程序供 Java 调用。只需将上面的 SPL 脚本存储为 count.splx 并在调用存储过程时在 Java 中调用它:
…
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
st = con.prepareCall("call count()");
st.execute();
…