
本文介绍使用 Java 8 Stream API 结合 org.json 库,从大型 JSON 数组中快速检测特定键(如 bookID)是否存在重复值,并返回所有重复 ID 列表。方法兼顾可读性、性能与实用性。
本文介绍使用 java 8 stream api 结合 org.json 库,从大型 json 数组中快速检测特定键(如 `bookid`)是否存在重复值,并返回所有重复 id 列表。方法兼顾可读性、性能与实用性。
在处理结构化 JSON 数据时,常需校验关键字段(如唯一标识符)是否重复,尤其在数据导入、ETL 或接口入参校验等场景中。以如下典型 JSON 为例:
{
"ID": "ID1",
"books": [
{ "bookID": "book1", "booktype": "pdf" },
{ "bookID": "book2", "booktype": "txt" },
{ "bookID": "book1", "booktype": "txt" }
]
}目标是高效识别 books 数组中 bookID 字段的重复项。对于大规模数据(数千至数万条记录),应避免嵌套循环,优先采用哈希分组 + 流式聚合策略。
✅ 推荐实现(Java 8+,基于 org.json)
以下代码使用 Collectors.groupingBy 按 bookID 分组,再筛选出元素数量 > 1 的组,最终提取重复 ID:
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class BookIdDuplicateDetector {
public static List<String> findDuplicateBookIds(String jsonString) throws JSONException {
JSONObject root = new JSONObject(jsonString);
JSONArray books = root.getJSONArray("books");
// 步骤1:按 bookID 分组,每个 key 对应一个 JSONObject 列表
Map<String, List<JSONObject>> grouped =
books.toList().stream()
.map(JSONObject.class::cast)
.collect(Collectors.groupingBy(
obj -> obj.optString("bookID", "")
));
// 步骤2:筛选出重复的 bookID(列表大小 ≥ 2)
return grouped.entrySet().stream()
.filter(entry -> entry.getValue().size() > 1)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
// 使用示例
public static void main(String[] args) throws JSONException {
String json = "{ \"ID\": \"ID1\", \"books\": ["
+ "{\"bookID\":\"book1\",\"booktype\":\"pdf\"},"
+ "{\"bookID\":\"book2\",\"booktype\":\"txt\"},"
+ "{\"bookID\":\"book1\",\"booktype\":\"txt\"}] }";
List<String> duplicates = findDuplicateBookIds(json);
if (duplicates.isEmpty()) {
System.out.println("✅ No duplicate book IDs found.");
} else {
System.out.println("⚠️ Duplicate book IDs: " + duplicates); // 输出: [book1]
}
}
}? 关键说明与注意事项
- 空值/缺失字段安全:使用 optString("bookID", "") 替代 getString(),避免 JSONException;空字符串也会被统一归类,可根据业务决定是否过滤(例如 .filter(id -> !id.isBlank()))。
- 性能优化:groupingBy 时间复杂度为 O(n),远优于双重循环 O(n²),适用于万级数据量。
-
依赖声明(Maven):
<dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20231013</version> </dependency> -
扩展建议:
- 若需返回完整重复对象(而不仅是 ID),可将 map(Map.Entry::getKey) 改为 map(entry -> new AbstractMap.SimpleEntry<>(entry.getKey(), entry.getValue()));
- 如需统计重复次数,可用 Collectors.collectingAndThen(Collectors.groupingBy(...), map -> map.entrySet().stream().filter(...)) 配合 Collectors.counting()。
该方案简洁、健壮、符合函数式编程思想,是 Java 处理 JSON 字段去重/校验的工业级实践。










