如何无需遍历将JSONArray添加到Set 解决合并去重时类型转换报错
报错根因
你使用的org.json包下的JSONArray没有实现Java标准Collection接口,因此既不能直接作为参数传入set.addAll(),也无法直接强转为ArrayList——二者不存在继承关系,强转只会触发运行时ClassCastException。
你尝试遍历后调用set.add()依旧报错,是因为遍历过程中没有正确取出JSONObject类型的元素,传入参数和HashSet声明的泛型类型不匹配。
除此之外还有一个隐藏逻辑问题:原生JSONObject没有重写equals()和hashCode()方法,即使两个对象的键值对完全一致,直接存入HashSet<JSONObject>也会被判定为不同元素,无法实现去重。
可直接运行的实现代码
最简便稳定的方案是借助JSON字符串做去重校验:相同内容的JSONObject调用toString()会输出完全一致的序列化结果,用字符串作为去重判断的依据即可准确过滤重复项,代码如下:
import org.json.JSONArray; import org.json.JSONObject; import java.util.HashSet; public JSONArray concatArray(JSONArray arr1, JSONArray arr2) { HashSet<String> duplicateSet = new HashSet<>(); JSONArray result = new JSONArray(); // 遍历处理第一个数组 for (int i = 0; i < arr1.length(); i++) { JSONObject item = arr1.getJSONObject(i); // add方法返回true代表元素首次出现,不属于重复项 if (duplicateSet.add(item.toString())) { result.put(item); } } // 遍历处理第二个数组 for (int i = 0; i < arr2.length(); i++) { JSONObject item = arr2.getJSONObject(i); if (duplicateSet.add(item.toString())) { result.put(item); } } return result; }
注意事项
- 该方案依赖
JSONObject.toString()的序列化稳定性,org.json原生实现对键值对完全相同的JSON对象会输出一致的字符串,只要你没有在JSON结构中存入未重写toString()的自定义对象、值动态变化的对象,去重结果就是可靠的。 - 如果需要更严谨的去重逻辑,可以自定义包装类封装
JSONObject,基于JSON所有键值对重写equals()和hashCode()方法,但实现成本更高,绝大多数业务场景下字符串去重方案已经足够。 - 遍历JSONArray取值时必须使用
getJSONObject(index)方法获取对应位置的元素,不要直接强转遍历得到的通用Object类型,避免触发类型转换异常。
内容的提问来源于stack exchange,提问作者MusicalChicken
相关产品推荐
相关产品推荐

