如何使自定义元组类通用?



我正在尝试创建一个通用元组类。它将其元素存储为数组列表。当然,此类应该覆盖哈希代码和等于方法。

如何为此类制作哈希代码方法?你看,在代码中,我遇到了麻烦。

另外,对于 equals 方法,为什么编译器强制我使用"?"。为什么我不能只使用 T?

public static class Tuple<T> { 
ArrayList<T> tuple = new ArrayList<>();
public Tuple(ArrayList<T> items) {
for (T item : items) {
tuple.add(item);
}
}
@Override
public int hashCode() {
T sum = ???;
for (T item : tuple) {
sum += item.hashCode();
}
return sum;
}
@Override 
public boolean equals(Object o) {
if (o instanceof Tuple<?>) {
Tuple<?> tup= (Tuple<?>) o;
if (tup.tuple.size() != this.tuple.size()) {
return false;
}
for (int i = 0; i < this.tuple.size(); i++) {
if (this.tuple.get(i) != tup.tuple.get(i)) {
return false;
} 
}
return true;
} else {
return false;
}
}
}

如注释中所述,我们应该将hashCodeequals方法委托给ArrayList<T> tuple实例变量。对于hashCode来说,这是微不足道的。对于equals来说,它只是比这复杂一点,因为我们不希望我们的自定义TupleArrayList相等。所以这里是:

public class Tuple<T> {
// I made this private because I'm pedantic ;)
private final ArrayList<T> tuple = new ArrayList<>();
// this does the same as your code, it's just easier to read
public Tuple(ArrayList<T> items) {
tuple.addAll(items);
}
@Override
public int hashCode() {
return tuple.hashCode();
}
// generated by eclipse
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Tuple other = (Tuple) obj;
if (tuple == null) {
if (other.tuple != null)
return false;
} else if (!tuple.equals(other.tuple))
return false;
return true;
}
}

如果要处理tuple可以为 null 的情况,则可以使用稍微复杂的hashCode

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((tuple == null) ? 0 : tuple.hashCode());
return tuple.hashCode();
}

一般来说,我不喜欢自己写这些方法。通常,我让我的IDE来生成东西。我需要做的就是在添加新字段时重新生成它。ApacheHashCodeBuilderEqualsBuilder也是不错的选择。

最新更新