即使您使用Set 接口的HashSet 实现,当两个集合包含相同的对象时,它也会产生相同的结果。因此,您无需对集合进行排序即可为两个不同但相等(包含相同对象)的集合生成相同的 JSON。
但如果你想强制 Jackson 在序列化之前对集合进行排序,你需要实现自定义序列化器。
我们只能为Set 注册序列化程序,它将用于包含Comparable 对象的集合和不包含对象的集合,因此必须在自定义实现中进行检查。
示例实现如下所示:
class SortedSetJsonSerializer extends JsonSerializer<Set> {
@Override
public void serialize(Set set, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (set == null) {
gen.writeNull();
return;
}
gen.writeStartArray();
if (!set.isEmpty()) {
// create sorted set only if it itself is not already SortedSet
if (!SortedSet.class.isAssignableFrom(set.getClass())) {
Object item = set.iterator().next();
if (Comparable.class.isAssignableFrom(item.getClass())) {
// and only if items are Comparable
set = new TreeSet(set);
}
}
for (Object item : set) {
gen.writeObject(item);
}
}
gen.writeEndArray();
}
}
以及示例用法:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.IntStream;
public class JsonApp {
public static void main(String[] args) throws Exception {
Set<Integer> ints = newSet();
SimpleModule module = new SimpleModule();
module.addSerializer(Set.class, new SortedSetJsonSerializer());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
System.out.println(mapper.writeValueAsString(new MyModel(ints)));
}
private static Set<Integer> newSet() {
Set<Integer> ints = new HashSet<>();
IntStream.range(10, 20).forEach(ints::add);
return ints;
}
}
class MyModel {
private Set<Integer> integers;
public MyModel(Set<Integer> integers) {
this.integers = integers;
}
public Set<Integer> getIntegers() {
return integers;
}
public void setIntegers(Set<Integer> integers) {
this.integers = integers;
}
}
打印:
{"integers":[10,11,12,13,14,15,16,17,18,19]}