Gson组成之JsonElement
- 抽象类,抽象方法是deepCopy()
- 是Gson数据类型的基础类,用来表示Json中的数据类型。其子类有对象(JsonObject),数组(JsonArray),空数据(JsonNull), JsonPrimitive(基本数据类型 byte/short/char/boolean/int/long/double/float/number/string) 用于标识各种数据类型
- 通过isJsonObject()/isJsonArray()/isJsonNull()/isJsonPrimitive()判断是否是四种类型
- 通过getAt方法只能直接获取四种类型,对于基本数据类型是没有做处理的,其实现类是JsonPrimitive
源码
import com.google.gson.JsonArray;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
* A class representing an element of Json. It could either be a {@link JsonObject}, a
* {@link JsonArray}, a {@link JsonPrimitive} or a {@link JsonNull}.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
public abstract class JsonElement {
/**
* 进行深拷贝
* 版本从2.2开始才有
* @return
*/
public abstract com.google.gson.JsonElement deepCopy();
/**
* 判断当前元素是不是jsonArray
* @return
*/
public boolean isJsonArray() {
return this instanceof JsonArray;
}
/**
* 判断当前元素是不是jsonObject
* @return
*/
public boolean isJsonObject() {
return this instanceof JsonObject;
}
/**
* 判断当前元素是不是基本数据类型
* @return
*/
public boolean isJsonPrimitive() {
return this instanceof JsonPrimitive;
}
/**
* 判断当前元素是不是空类型
* @return
*/
public boolean isJsonNull() {
return this instanceof JsonNull;
}
/**
* 将当前对象转换为jsonObject进行返回 若不是jsonObject类型 将会抛异常
* @return
*/
public JsonObject getAsJsonObject() {
if (isJsonObject()) {
return (JsonObject) this;
}
throw new IllegalStateException("Not a JSON Object: " + this);
}
/**
* 将当前对象转换为jsonArray进行返回 若不是jsonArray类型 将会抛异常
* @return
*/
public JsonArray getAsJsonArray() {
if (isJsonArray()) {
return (JsonArray) this;
}
throw new IllegalStateException("Not a JSON Array: " + this);
}
/**
* 将当前对象转换为jsonPrimitive进行返回 若不是jsonPrimitive类型 将会抛异常
* @return
*/
public JsonPrimitive getAsJsonPrimitive() {
if (isJsonPrimitive()) {
return (JsonPrimitive) this;
}
throw new IllegalStateException("Not a JSON Primitive: " + this);
}
/**
* 将当前对象转换为jsonNull进行返回 若不是jsonNull类型 将会抛异常
* @return
*/
public JsonNull getAsJsonNull() {
if (isJsonNull()) {
return (JsonNull) this;
}
throw new IllegalStateException("Not a JSON Null: " + this);
}
/**
* 将当前对象转换为boolean进行返回 未实现
* @return
*/
public boolean getAsBoolean() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
/**
* 将当前对象转换为number进行返回 未实现
* @return
*/
public Number getAsNumber() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
/**
* 将当前对象转换为string进行返回 未实现
* @return
*/
public String getAsString() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
/**
* 将当前对象转换为double进行返回 未实现
* @return
*/
public double getAsDouble() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
/**
* 将当前对象转换为float进行返回 未实现
* @return
*/
public float getAsFloat() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
/**
* 将当前对象转换为long进行返回 未实现
* @return
*/
public long getAsLong() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
/**
* 将当前对象转换为int进行返回 未实现
* @return
*/
public int getAsInt() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
/**
* 将当前对象转换为byte进行返回 未实现
* @return
*/
public byte getAsByte() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
/**
* 将当前对象转换为Character进行返回 未实现
* @return
*/
@Deprecated
public char getAsCharacter() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
/**
* 将当前对象转换为BigDecimal进行返回 未实现
* @return
*/
public BigDecimal getAsBigDecimal() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
/**
* 将当前对象转换为BigInteger进行返回 未实现
* @return
*/
public BigInteger getAsBigInteger() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
/**
* 将当前对象转换为Short进行返回 未实现
* @return
*/
public short getAsShort() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
/**
* Returns a String representation of this element.
*/
@Override
public String toString() {
try {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.setLenient(true);
Streams.write(this, jsonWriter);
return stringWriter.toString();
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
JsonElement子类之JsonNull
- 继承于JsonElement
- 用final修饰,不可被继承
- 没有做任何事,只是把创建的静态实例在deepCopy中被返回
源码
import com.google.gson.JsonElement;
public final class JsonNull extends JsonElement {
/**
* 静态实例
*/
public static final com.google.gson.JsonNull INSTANCE = new com.google.gson.JsonNull();
/**
* 在构造函数中没有做任何操作
*/
@Deprecated
public JsonNull() {
// Do nothing
}
/**
* 在深拷贝中将实例返回
* @return
*/
@Override
public com.google.gson.JsonNull deepCopy() {
return INSTANCE;
}
@Override
public int hashCode() {
return com.google.gson.JsonNull.class.hashCode();
}
@Override
public boolean equals(Object other) {
return this == other || other instanceof com.google.gson.JsonNull;
}
}
JsonElement子类之JsonObject
- 继承于JsonElement
- 用final修饰,不能被继承
- 使用LinkedTreeMap的key/value来存储数据
方法说明
add 可直接添加String/Number/Boolean/Character(将其转换为JsonPrimitive) 以及JsonElement
get getJsonObject/getJsonArray/JsonPrimitive/JsonElement
remove 通过key来移除数据
size 获取集合的大小
has 判断是否包含对应的key
keySet/entrySet 进行迭代
源码
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonPrimitive;
import com.google.gson.internal.LinkedTreeMap;
import java.util.Map;
import java.util.Set;
public final class JsonObject extends com.google.gson.JsonElement {
/**
* LinkedTreeMap是HashMap的一个子类
* key:String
* value:JsonElement
*/
private final LinkedTreeMap<String, com.google.gson.JsonElement> members =
new LinkedTreeMap<String, com.google.gson.JsonElement>();
/**
* 深度复制
* 1.创建一个对象 并把map中的值复制到对象中 返回返回
* @return
*/
@Override
public com.google.gson.JsonObject deepCopy() {
com.google.gson.JsonObject result = new com.google.gson.JsonObject();
for (Map.Entry<String, com.google.gson.JsonElement> entry : members.entrySet()) {
result.add(entry.getKey(), entry.getValue().deepCopy());
}
return result;
}
/**
* 添加JsonElement 数据到数组中
* @param property key
* @param value 判断是否为空 若为空 value为JsonNull 若不为空 则value为原始值
*/
public void add(String property, com.google.gson.JsonElement value) {
members.put(property, value == null ? com.google.gson.JsonNull.INSTANCE : value);
}
/**
* 移除key value 数据从数组中
* @param property key
*/
public com.google.gson.JsonElement remove(String property) {
return members.remove(property);
}
/**
* 添加string类型数据到map中
* @param property
* @param value 若value为空则存储JsonNull,反之包装成Primitive进行存储
*/
public void addProperty(String property, String value) {
add(property, value == null ? com.google.gson.JsonNull.INSTANCE : new com.google.gson.JsonPrimitive(value));
}
/**
* 添加number类型数据到map中
* @param property
* @param value 若value为空则存储JsonNull,反之包装成Primitive进行存储
*/
public void addProperty(String property, Number value) {
add(property, value == null ? com.google.gson.JsonNull.INSTANCE : new com.google.gson.JsonPrimitive(value));
}
/**
* 添加boolean类型数据到map中
* @param property
* @param value 若value为空则存储JsonNull,反之包装成Primitive进行存储
*/
public void addProperty(String property, Boolean value) {
add(property, value == null ? com.google.gson.JsonNull.INSTANCE : new com.google.gson.JsonPrimitive(value));
}
/**
* 添加Character类型数据到map中
* @param property
* @param value 若value为空则存储JsonNull,反之包装成Primitive进行存储
*/
public void addProperty(String property, Character value) {
add(property, value == null ? JsonNull.INSTANCE : new om.google.gson.JsonPrimitive(value));
}
/**
* 获取容器的set集合
* @return
*/
public Set<Map.Entry<String, com.google.gson.JsonElement>> entrySet() {
return members.entrySet();
}
/**
* 获取容器的key集合
* @return
*/
public Set<String> keySet() {
return members.keySet();
}
/**
* 获取容器的大小
* @return
*/
public int size() {
return members.size();
}
/**
* 判断key值在集合中是否存在
* @param memberName
* @return
*/
public boolean has(String memberName) {
return members.containsKey(memberName);
}
/**
* 根据key值获取对应的value
* @param memberName
* @return
*/
public JsonElement get(String memberName) {
return members.get(memberName);
}
/**
* 根据key值获取对应的JsonPrimitive
* @param memberName
* @return
*/
public com.google.gson.JsonPrimitive getAsJsonPrimitive(String memberName) {
return (JsonPrimitive) members.get(memberName);
}
/**
* 根据key值获取对应的JsonArray
* @param memberName
* @return
*/
public JsonArray getAsJsonArray(String memberName) {
return (JsonArray) members.get(memberName);
}
/**
* 根据key值获取对应的JsonObject
* @param memberName
* @return
*/
public com.google.gson.JsonObject getAsJsonObject(String memberName) {
return (com.google.gson.JsonObject) members.get(memberName);
}
@Override
public boolean equals(Object o) {
return (o == this) || (o instanceof com.google.gson.JsonObject
&& ((com.google.gson.JsonObject) o).members.equals(members));
}
@Override
public int hashCode() {
return members.hashCode();
}
}
JsonElement子类之JsonArray
- 继承于JsonElement,并实现Iterable
- 用final修饰,不能被继承
- 使用list结合才存储元素
方法说明
add 可直接添加String/Boolean/Number/Character(将其转换为JsonPrimitive) ,以及JsonElement/JsonArray
get 根据索引值获取对应的value
remove 根据索引移除元素
getAs 获取各种数据元素
size 获取集合大小
源码
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonPrimitive;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public final class JsonArray extends com.google.gson.JsonElement implements Iterable<com.google.gson.JsonElement> {
/**
* 使用list集合进行操作
*/
private final List<com.google.gson.JsonElement> elements;
/**
* 无参数构造函数 默认初始化elements
*/
public JsonArray() {
elements = new ArrayList<com.google.gson.JsonElement>();
}
/**
* 有参数构造函数 初始化elements时指定容器大小
* @param capacity
*/
public JsonArray(int capacity) {
elements = new ArrayList<com.google.gson.JsonElement>(capacity);
}
/**
* 深度复制
* 判断集合是否为空 若为空 则创建一个空的jsonArray对象
* 若不为空 则创建一个一个JsonArray 将list中的元素全部拷贝进去,之后返回
* @return
*/
@Override
public com.google.gson.JsonArray deepCopy() {
if (!elements.isEmpty()) {
com.google.gson.JsonArray result = new com.google.gson.JsonArray(elements.size());
for (com.google.gson.JsonElement element : elements) {
result.add(element.deepCopy());
}
return result;
}
return new com.google.gson.JsonArray();
}
/**
* 添加boolean类型数据 将其包装成JsonPrimitive
* @param bool
*/
public void add(Boolean bool) {
elements.add(bool == null ? com.google.gson.JsonNull.INSTANCE : new com.google.gson.JsonPrimitive(bool));
}
/**
* 添加Character类型数据 将其包装成JsonPrimitive
*/
public void add(Character character) {
elements.add(character == null ? com.google.gson.JsonNull.INSTANCE : new com.google.gson.JsonPrimitive(character));
}
/**
* 添加Number类型数据 将其包装成JsonPrimitive
*/
public void add(Number number) {
elements.add(number == null ? com.google.gson.JsonNull.INSTANCE : new com.google.gson.JsonPrimitive(number));
}
/**
* 添加String类型数据 将其包装成JsonPrimitive
*/
public void add(String string) {
elements.add(string == null ? com.google.gson.JsonNull.INSTANCE : new com.google.gson.JsonPrimitive(string));
}
/**
* 添加JsonElement类型数据 将其包装成JsonPrimitive
*/
public void add(com.google.gson.JsonElement element) {
if (element == null) {
element = JsonNull.INSTANCE;
}
elements.add(element);
}
/**
* 添加jsonArray
* @param array
*/
public void addAll(com.google.gson.JsonArray array) {
elements.addAll(array.elements);
}
/**
* 对集合对应位置设置数据
* @param index
* @param element
* @return
*/
public com.google.gson.JsonElement set(int index, com.google.gson.JsonElement element) {
return elements.set(index, element);
}
/**
* 根据value值来进行移除
* @param element
* @return
*/
public boolean remove(com.google.gson.JsonElement element) {
return elements.remove(element);
}
/**
* 根据key值来进行移除
* @param element
* @return
*/
public com.google.gson.JsonElement remove(int index) {
return elements.remove(index);
}
/**
* 判断集合是否包含该元素
* @param element
* @return
*/
public boolean contains(com.google.gson.JsonElement element) {
return elements.contains(element);
}
/**
* 返回集合大小
* @return
*/
public int size() {
return elements.size();
}
/**
* 迭代器进行处理
* @return
*/
public Iterator<com.google.gson.JsonElement> iterator() {
return elements.iterator();
}
/**
* 根据索引获取对应的value
* @return
*/
public JsonElement get(int i) {
return elements.get(i);
}
/**
* 将集合的第一个元素转换为number
* @return
*/
@Override
public Number getAsNumber() {
if (elements.size() == 1) {
return elements.get(0).getAsNumber();
}
throw new IllegalStateException();
}
/**
* 将集合的第一个元素转换为String
* @return
*/
@Override
public String getAsString() {
if (elements.size() == 1) {
return elements.get(0).getAsString();
}
throw new IllegalStateException();
}
/**
* 将集合的第一个元素转换为String
* @return
*/
@Override
public double getAsDouble() {
if (elements.size() == 1) {
return elements.get(0).getAsDouble();
}
throw new IllegalStateException();
}
/**
* 将集合的第一个元素转换为String
* @return
*/
@Override
public BigDecimal getAsBigDecimal() {
if (elements.size() == 1) {
return elements.get(0).getAsBigDecimal();
}
throw new IllegalStateException();
}
/**
* 将集合的第一个元素转换为String
* @return
*/
@Override
public BigInteger getAsBigInteger() {
if (elements.size() == 1) {
return elements.get(0).getAsBigInteger();
}
throw new IllegalStateException();
}
/**
* 将集合的第一个元素转换为String
* @return
*/
@Override
public float getAsFloat() {
if (elements.size() == 1) {
return elements.get(0).getAsFloat();
}
throw new IllegalStateException();
}
/**
* convenience method to get this array as a long if it contains a single element.
*
* @return get this element as a long if it is single element array.
* @throws ClassCastException if the element in the array is of not a {@link com.google.gson.JsonPrimitive} and
* is not a valid long.
* @throws IllegalStateException if the array has more than one element.
*/
@Override
public long getAsLong() {
if (elements.size() == 1) {
return elements.get(0).getAsLong();
}
throw new IllegalStateException();
}
/**
* convenience method to get this array as an integer if it contains a single element.
*
* @return get this element as an integer if it is single element array.
* @throws ClassCastException if the element in the array is of not a {@link com.google.gson.JsonPrimitive} and
* is not a valid integer.
* @throws IllegalStateException if the array has more than one element.
*/
@Override
public int getAsInt() {
if (elements.size() == 1) {
return elements.get(0).getAsInt();
}
throw new IllegalStateException();
}
@Override
public byte getAsByte() {
if (elements.size() == 1) {
return elements.get(0).getAsByte();
}
throw new IllegalStateException();
}
@Override
public char getAsCharacter() {
if (elements.size() == 1) {
return elements.get(0).getAsCharacter();
}
throw new IllegalStateException();
}
/**
* convenience method to get this array as a primitive short if it contains a single element.
*
* @return get this element as a primitive short if it is single element array.
* @throws ClassCastException if the element in the array is of not a {@link com.google.gson.JsonPrimitive} and
* is not a valid short.
* @throws IllegalStateException if the array has more than one element.
*/
@Override
public short getAsShort() {
if (elements.size() == 1) {
return elements.get(0).getAsShort();
}
throw new IllegalStateException();
}
/**
* convenience method to get this array as a boolean if it contains a single element.
*
* @return get this element as a boolean if it is single element array.
* @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
* is not a valid boolean.
* @throws IllegalStateException if the array has more than one element.
*/
@Override
public boolean getAsBoolean() {
if (elements.size() == 1) {
return elements.get(0).getAsBoolean();
}
throw new IllegalStateException();
}
@Override
public boolean equals(Object o) {
return (o == this) || (o instanceof com.google.gson.JsonArray && ((com.google.gson.JsonArray) o).elements.equals(elements));
}
@Override
public int hashCode() {
return elements.hashCode();
}
}
JsonElement子类之JsonPrimtive
- 继承于JsonElement,用于包装各种基本数据类型
- 用final修饰,不能被继承
- 在构造函数中可传递Boolean/String/Number/Char类型数据
- 通过isBoolean()/isNumber()/isInteger()/isString()来判断数据类型
- 重写了JsonElement的get方法来实现基本数据类型的返回
源码
import com.google.gson.JsonElement;
import com.google.gson.internal.$Gson$Preconditions;
import com.google.gson.internal.LazilyParsedNumber;
import java.math.BigDecimal;
import java.math.BigInteger;
public final class JsonPrimitive extends JsonElement {
private final Object value;
/**
* 在构造函数中 默认创建一个boolean类型的对象
* @param bool
*/
public JsonPrimitive(Boolean bool) {
//检测参数bool是否为空 为空抛异常 不为空则将值返回
value = $Gson$Preconditions.checkNotNull(bool);
}
/**
* 在构造函数中 默认创建一个Number类型的对象
* @param bool
*/
public JsonPrimitive(Number number) {
//检测参数bool是否为空 为空抛异常 不为空则将值返回
value = $Gson$Preconditions.checkNotNull(number);
}
public JsonPrimitive(String string)
{
//检测参数bool是否为空 为空抛异常 不为空则将值返回
value = $Gson$Preconditions.checkNotNull(string);
}
public JsonPrimitive(Character c) {
// convert characters to strings since in JSON, characters are represented as a single
// character string
value = $Gson$Preconditions.checkNotNull(c).toString();
}
/**
* 深拷贝对象 直接将该对象返回
* @return
*/
@Override
public com.google.gson.JsonPrimitive deepCopy() {
return this;
}
/**
* 判断类型是不是boolean类型
* @return
*/
public boolean isBoolean() {
return value instanceof Boolean;
}
/**
* 判断类型是不是number类型
* @return
*/
public boolean isNumber() {
return value instanceof Number;
}
/**
* 判断类型是不是String类型
* @return
*/
public boolean isString() {
return value instanceof String;
}
/**
* 判断类型是不是integer类型
* @return
*/
private static boolean isIntegral(com.google.gson.JsonPrimitive primitive) {
if (primitive.value instanceof Number) {
Number number = (Number) primitive.value;
return number instanceof BigInteger || number instanceof Long || number instanceof Integer
|| number instanceof Short || number instanceof Byte;
}
return false;
}
/**
* 将值以boolean类型进行返回
* @return
*/
@Override
public boolean getAsBoolean() {
//若是boolean类型直接返回
if (isBoolean()) {
return ((Boolean) value).booleanValue();
}
//若不是boolean类型 先转换为string类型 然后转换为boolean类型
return Boolean.parseBoolean(getAsString());
}
/**
* 将值以number类型进行返回
* @return
*/
@Override
public Number getAsNumber() {
return value instanceof String ? new LazilyParsedNumber((String) value) : (Number) value;
}
/**
* 将值以String类型进行返回
* @return
*/
@Override
public String getAsString() {
if (isNumber()) {
return getAsNumber().toString();
} else if (isBoolean()) {
return ((Boolean) value).toString();
} else {
return (String) value;
}
}
/**
* 以char类型进行返回
* @return
*/
@Override
public char getAsCharacter() {
return getAsString().charAt(0);
}
/**
* 以double类型进行返回
* @return
*/
@Override
public double getAsDouble() {
return isNumber() ? getAsNumber().doubleValue() : Double.parseDouble(getAsString());
}
/**
* convenience method to get this element as a {@link BigDecimal}.
*
* @return get this element as a {@link BigDecimal}.
* @throws NumberFormatException if the value contained is not a valid {@link BigDecimal}.
*/
@Override
public BigDecimal getAsBigDecimal() {
return value instanceof BigDecimal ? (BigDecimal) value : new BigDecimal(value.toString());
}
/**
* convenience method to get this element as a {@link BigInteger}.
*
* @return get this element as a {@link BigInteger}.
* @throws NumberFormatException if the value contained is not a valid {@link BigInteger}.
*/
@Override
public BigInteger getAsBigInteger() {
return value instanceof BigInteger ?
(BigInteger) value : new BigInteger(value.toString());
}
/**
* convenience method to get this element as a float.
*
* @return get this element as a float.
* @throws NumberFormatException if the value contained is not a valid float.
*/
@Override
public float getAsFloat() {
return isNumber() ? getAsNumber().floatValue() : Float.parseFloat(getAsString());
}
/**
* convenience method to get this element as a primitive long.
*
* @return get this element as a primitive long.
* @throws NumberFormatException if the value contained is not a valid long.
*/
@Override
public long getAsLong() {
return isNumber() ? getAsNumber().longValue() : Long.parseLong(getAsString());
}
/**
* convenience method to get this element as a primitive short.
*
* @return get this element as a primitive short.
* @throws NumberFormatException if the value contained is not a valid short value.
*/
@Override
public short getAsShort() {
return isNumber() ? getAsNumber().shortValue() : Short.parseShort(getAsString());
}
/**
* convenience method to get this element as a primitive integer.
*
* @return get this element as a primitive integer.
* @throws NumberFormatException if the value contained is not a valid integer.
*/
@Override
public int getAsInt() {
return isNumber() ? getAsNumber().intValue() : Integer.parseInt(getAsString());
}
@Override
public byte getAsByte() {
return isNumber() ? getAsNumber().byteValue() : Byte.parseByte(getAsString());
}
@Override
public int hashCode() {
if (value == null) {
return 31;
}
// Using recommended hashing algorithm from Effective Java for longs and doubles
if (isIntegral(this)) {
long value = getAsNumber().longValue();
return (int) (value ^ (value >>> 32));
}
if (value instanceof Number) {
long value = Double.doubleToLongBits(getAsNumber().doubleValue());
return (int) (value ^ (value >>> 32));
}
return value.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
com.google.gson.JsonPrimitive other = (com.google.gson.JsonPrimitive)obj;
if (value == null) {
return other.value == null;
}
if (isIntegral(this) && isIntegral(other)) {
return getAsNumber().longValue() == other.getAsNumber().longValue();
}
if (value instanceof Number && other.value instanceof Number) {
double a = getAsNumber().doubleValue();
// Java standard types other than double return true for two NaN. So, need
// special handling for double.
double b = other.getAsNumber().doubleValue();
return a == b || (Double.isNaN(a) && Double.isNaN(b));
}
return value.equals(other.value);
}
}