
在java开发中,我们经常需要处理来自外部服务或文件中的json数据。有时,这些json结构可能比较复杂,例如包含多层嵌套的数组,并且需要从这些嵌套数据中提取并聚合信息。
考虑以下JSON结构,它是一个多层嵌套的数组,每一层内部数组包含多个对象,每个对象有word和count字段:
[
[
{"word": "china", "count": 0},
{"word": "kids", "count": 1},
{"word": "music", "count": 0}
],
[
{"word": "china", "count": 3},
{"word": "kids", "count": 0},
{"word": "music", "count": 2}
],
[
{"word": "china", "count": 10},
{"word": "kids", "count": 3},
{"word": "music", "count": 2}
]
]我们的目标是将这个复杂的JSON数据转换为一个简洁的Java POJO列表。对于每个唯一的word,我们需要计算它在所有嵌套数组中count字段的最小值(min)和最大值(max),并将其映射到如下的Word POJO中:
public class Word {
private String text;
private Integer min;
private Integer max;
// Getters and Setters
}例如,对于"china"这个词,其count值分别为0、3、10。因此,转换后对应的Word对象应为text="china", min=0, max=10。
首先,定义用于接收转换后数据的Word POJO。为了让Jackson能够正确地进行反序列化,需要为字段提供公共的setter方法。
立即学习“Java免费学习笔记(深入)”;
public class Word {
private String text;
private Integer min;
private Integer max;
public void setText(String text) {
this.text = text;
}
public void setMin(Integer min) {
this.min = min;
}
public void setMax(Integer max) {
this.max = max;
}
@Override
public String toString() {
return String.format("text=%s min=%d max=%d", text, min, max);
}
}直接使用Jackson处理这种复杂的聚合和转换逻辑会非常繁琐,可能需要编写自定义的反序列化器。幸运的是,我们可以利用Josson这个强大的JSON处理库,在反序列化之前对JSON数据进行预处理和转换。Josson提供了一套类似XPath的查询语言,可以方便地进行数据的过滤、转换、分组和聚合。
要在项目中集成Josson和Jackson,需要在pom.xml(Maven项目)或build.gradle(Gradle项目)中添加相应的依赖:
Maven:
<dependencies>
<dependency>
<groupId>com.octomix.josson</groupId>
<artifactId>josson</artifactId>
<version>1.2.3</version> <!-- 请使用最新版本 -->
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version> <!-- 请使用最新版本 -->
</dependency>
</dependencies>为了演示,我们将原始JSON字符串硬编码。在实际应用中,这通常是从文件、网络请求或其他数据源获取的。
String jsonString = "[" +
" [" +
" {\"word\": \"china\", \"count\": 0}," +
" {\"word\": \"kids\", \"count\": 1}," +
" {\"word\": \"music\", \"count\": 0}" +
" ]," +
" [" +
" {\"word\": \"china\", \"count\": 3}," +
" {\"word\": \"kids\", \"count\": 0}," +
" {\"word\": \"music\", \"count\": 2}" +
" ]," +
" [" +
" {\"word\": \"china\", \"count\": 10}," +
" {\"word\": \"kids\", \"count\": 3}," +
" {\"word\": \"music\", \"count\": 2}" +
" ]" +
"]";Josson的核心在于其强大的表达式语言。为了达到我们的目标,我们将使用以下Josson表达式:
flatten().group(word).map(text:word, min:elements.min(count), max:elements.max(count))
让我们逐一解析这个表达式:
flatten(): 这个函数用于将多层嵌套的数组扁平化为一层数组。原始JSON是一个包含数组的数组,flatten()会将其转换为一个单一的包含所有word对象的数组。 例如,经过flatten()后,数据结构将类似于: [{"word": "china", "count": 0}, {"word": "kids", "count": 1}, ..., {"word": "china", "count": 10}, ...]
group(word): 在扁平化之后,我们希望对数据按word字段进行分组。group(word)会将所有具有相同word值的对象归类到一起。每个分组会包含一个word键(作为分组依据)和一个elements键(包含该分组下的所有原始元素)。
map(text:word, min:elements.min(count), max:elements.max(count)): map()函数用于将每个分组转换为我们期望的输出格式。它允许我们重命名字段并进行聚合操作。
Josson转换后的结果是一个JsonNode对象,其结构已经与我们的Word POJO列表相匹配。此时,我们可以使用Jackson的ObjectMapper将其轻松地反序列化为List<Word>。
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.octomix.josson.Josson;
// ... (Word POJO definition)
public class JsonToPojoConverter {
public static void main(String[] args) throws Exception {
String jsonString = "[" +
" [" +
" {\"word\": \"china\", \"count\": 0}," +
" {\"word\": \"kids\", \"count\": 1}," +
" {\"word\": \"music\", \"count\": 0}" +
" ]," +
" [" +
" {\"word\": \"china\", \"count\": 3}," +
" {\"word\": \"kids\", \"count\": 0}," +
" {\"word\": \"music\", \"count\": 2}" +
" ]," +
" [" +
" {\"word\": \"china\", \"count\": 10}," +
" {\"word\": \"kids\", \"count\": 3}," +
" {\"word\": \"music\", \"count\": 2}" +
" ]" +
"]";
// 1. 使用Josson解析JSON字符串
Josson josson = Josson.fromJsonString(jsonString);
// 2. 执行Josson转换表达式
JsonNode node = josson.getNode(
"flatten()" +
".group(word)" +
".map(text:word, min:elements.min(count), max:elements.max(count))"
);
// 3. 使用Jackson将转换后的JsonNode反序列化为List<Word>
ObjectMapper objectMapper = new ObjectMapper();
List<Word> words = objectMapper.convertValue(node, new TypeReference<List<Word>>() {});
// 4. 打印结果
words.forEach(System.out::println);
}
}执行上述代码,将得到以下输出:
text=china min=0 max=10 text=kids min=0 max=3 text=music min=0 max=2
这正是我们期望的结果,每个单词的min和max出现次数都被正确计算并映射到了Word POJO中。
通过本教程,我们学习了如何巧妙地结合Josson和Jackson,高效地处理嵌套JSON数据,并进行复杂的聚合计算,最终将其转换为符合业务需求的Java POJO。这种方法显著简化了数据处理逻辑,提升了开发效率和代码的可维护性。
以上就是从嵌套JSON中提取并计算元素最小最大出现次数的Java实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号