IDEA可以直接生成简单的toString、hashCode以及equals方法,但有的时候是不够的。
Commonclipse,生成hashcode、equals方法的插件。
Guava对toStirng、hashCode、equals方法进行了支持,使得自定义变得更简单。
Objects
Guava中的Objects类可以进行equals、hashCode方法的自定义。
package com.google.common.base;
@GwtCompatible
public final class Objects extends ExtraObjectsMethodsForWeb {
private Objects() {}
public static boolean equal(@Nullable Object a, @Nullable Object b) {
return a == b || (a != null && a.equals(b));
}
public static int hashCode(@Nullable Object... objects) {
return Arrays.hashCode(objects);
}
}
class Demo {
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Demo demo = (demo) o;
return Objects.equal(this.name, guava.name)
&& Objects.equal(this.age, guava.age)
&& Objects.equal(this.birthday, guava.birthday);
}
@Override
public int hashCode() {
// Guava Objects hashCode 底层调用了 Arrays.hashCode
return Objects.hashCode(name,age,birthday);
}
}
MoreObjects
Guava中的MoreObjecs提供了toString方法自定义的支持。
@GwtCompatible
public final class MoreObjects {
// 返回两个给定参数第一个不为空的参数,如果都是空,抛出NullPointerException
public static <T> T firstNonNull(@Nullable T first, @Nullable T second) {
return first != null ? first : checkNotNull(second);
}
// 返回ToStringHelper对象(内部类)
public static ToStringHelper toStringHelper(Object self) {
return new ToStringHelper(self.getClass().getSimpleName());
}
public static ToStringHelper toStringHelper(Class<?> clazz) {
return new ToStringHelper(clazz.getSimpleName());
}
public static ToStringHelper toStringHelper(String className) {
return new ToStringHelper(className);
}
public static final class ToStringHelper {
private final String className;
private final ValueHolder holderHead = new ValueHolder();
private ValueHolder holderTail = holderHead;
private boolean omitNullValues = false;
private ToStringHelper(String className) {
this.className = checkNotNull(className);
}
// 省略值为null的字段
@CanIgnoreReturnValue
public ToStringHelper omitNullValues() {
omitNullValues = true;
return this;
}
// 添加属性以及对应的值
@CanIgnoreReturnValue
public ToStringHelper add(String name, @Nullable Object value) {
return addHolder(name, value);
}
@CanIgnoreReturnValue
public ToStringHelper addValue(@Nullable Object value) {
return addHolder(value);
}
@Override
public String toString() {
// create a copy to keep it consistent in case value changes
boolean omitNullValuesSnapshot = omitNullValues;
String nextSeparator = "";
StringBuilder builder = new StringBuilder(32).append(className).append('{');
for (ValueHolder valueHolder = holderHead.next;
valueHolder != null;
valueHolder = valueHolder.next) {
Object value = valueHolder.value;
if (!omitNullValuesSnapshot || value != null) {
builder.append(nextSeparator);
nextSeparator = ", ";
if (valueHolder.name != null) {
builder.append(valueHolder.name).append('=');
}
if (value != null && value.getClass().isArray()) {
Object[] objectArray = {value};
String arrayString = Arrays.deepToString(objectArray);
builder.append(arrayString, 1, arrayString.length() - 1);
} else {
builder.append(value);
}
}
}
return builder.append('}').toString();
}
// 添加节点
private ValueHolder addHolder() {
ValueHolder valueHolder = new ValueHolder();
holderTail = holderTail.next = valueHolder;
return valueHolder;
}
private ToStringHelper addHolder(@Nullable Object value) {
ValueHolder valueHolder = addHolder();
valueHolder.value = value;
return this;
}
private ToStringHelper addHolder(String name, @Nullable Object value) {
ValueHolder valueHolder = addHolder();
valueHolder.value = value;
valueHolder.name = checkNotNull(name);
return this;
}
// 属性名-属性值 节点对象,像链表一样串在一起
private static final class ValueHolder {
String name;
Object value;
ValueHolder next;
}
}
private MoreObjects() {}
}
class Deom {
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.omitNullValues() // 省略空
.add("name", this.name) // 添加属性名、属性值
.add("age", this.age)
.add("birthday", this.birthday)
.toString(); // MoreObjects核心方法
}
}
ComparisonChain
ComparisonChain是Guava提供的一个比较器,它可以简化手动十天compareTo方法时大量if-else代码的出现,使比较器变得优雅。
class Demo {
@Override
public int compareTo(Guava o) {
return ComparisonChain.start()
.compare(this.name, o.name)
.compare(this.age, o.age)
.compare(this.birthday, o.birthday)
.result();
}
}
ComparisonChain是一个抽象类,内部主要有三个方法。
public abstract class ComparisonChain {
// 构造私有,只提供静态方法
private ComparisonChain() {}
// 返回ComparisonChain的一个内部类对象,该内部类中进行了抽象方法的实现
public static ComparisonChain start() {
return ACTIVE;
}
// 大量比较方法的重载,由内部类进行了实现
public abstract ComparisonChain compare(Comparable<?> left, Comparable<?> right)
// 返回了比较的结果,在内部类中进行了实现
public abstract int result();
}