getUserInfo
默认不提供任何缓存实例并检查实例是否已被看到的方法。为此,我们需要实现自定义Gson
。另外,我们需要假设com.google.gson.TypeAdapterFactory
类(如果需要,还可以使用Car
类)正确实现了Person
和public boolean equals(Object o)
,因此我们可以使用public int hashCode()
来缓存所有实例
让我们假设您的模型如下所示:
Map
class Model {
private Car car;
private Person person;
// getters,setters,toString
}
class Person {
private int id;
private String name;
private Car car;
// getters,toString
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return id == person.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
class Car {
private int id;
private String name;
// getters,toString
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Car car = (Car) o;
return id == car.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
和Car
类具有Person
字段,我们使用它们来区分实例。您可以在实现中使用所需的任何属性。
使用id
缓存实例的自定义适配器实现:
Map
然后在下面找到如何使用它的示例:
class CachedInstancesTypeAdapterFactory implements TypeAdapterFactory {
private final Map<Class,Map> cachedMaps = new HashMap<>();
public CachedInstancesTypeAdapterFactory(Set<Class> customizedClasses) {
Objects.requireNonNull(customizedClasses);
customizedClasses.forEach(clazz -> cachedMaps.compute(clazz,(c,m) -> new HashMap<>()));
}
public final <T> TypeAdapter<T> create(Gson gson,TypeToken<T> type) {
if (cachedMaps.containsKey(type.getRawType())) {
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this,type);
return createCustomTypeAdapter(delegate);
}
return null;
}
@SuppressWarnings("unchecked")
private <T> TypeAdapter<T> createCustomTypeAdapter(TypeAdapter<T> delegate) {
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out,T value) throws IOException {
delegate.write(out,value);
}
@Override
public T read(JsonReader in) throws IOException {
Object deserialized = delegate.read(in);
Map tInstances = Objects.requireNonNull(cachedMaps.get(deserialized.getClass()));
return (T) tInstances.computeIfAbsent(deserialized,k -> deserialized);
}
};
}
}
上面的代码打印出来,首先是import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
public class GsonApp {
public static void main(String[] args) {
Gson gson = createGson();
String json = gson.toJson(createModel());
System.out.println(json);
Model result = gson.fromJson(json,Model.class);
System.out.println(result);
System.out.println("Two car instances are the same: " + (result.getCar() == result.getPerson().getCar()));
}
private static Model createModel() {
Car car = new Car();
car.setId(9943);
car.setName("Honda");
Person person = new Person();
person.setId(123);
person.setName("Jon");
person.setCar(car);
Model model = new Model();
model.setCar(car);
model.setPerson(person);
return model;
}
private static Gson createGson() {
Set<Class> classes = new HashSet<>();
classes.add(Car.class);
classes.add(Person.class);
return new GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapterFactory(new CachedInstancesTypeAdapterFactory(classes))
.create();
}
}
:
JSON
然后:
{
"car": {
"id": 9943,"name": "Honda"
},"person": {
"id": 123,"name": "Jon","car": {
"id": 9943,"name": "Honda"
}
}
}
注意
在Model{car=Car{id=9943,name='Honda'},person=Person{id=123,name='Jon',car=Car{id=9943,name='Honda'}}}
Two car instances are the same: true
之上的实现不是线程安全的。此外,当您想使用CachedInstancesTypeAdapterFactory
和Gson
实例反序列化JSON
有效负载时,必须为每个线程和每次尝试创建一个总是新的Car
对象。原因是Person
对象只能使用一次。
另请参阅:
本文链接:https://www.f2er.com/3108569.html