Java中自定义双向链表equals方法如何区分空的不同泛型实例?
解决自定义双向链表不同泛型空链表equals判定问题
因为Java泛型采用类型擦除机制,运行时无法直接获取泛型的实际类型,所以需要手动在链表类中保存元素类型信息,具体实现步骤如下:
1. 在链表类中添加类型成员
修改MyDoublyLinkedList<E>的定义,新增一个Class<E>类型的成员变量,用来存储泛型的实际类型,通过构造方法传入:
public class MyDoublyLinkedList<E> { private final Class<E> elementType; // 原有成员:头节点、尾节点、大小等 // 带类型参数的构造方法 public MyDoublyLinkedList(Class<E> elementType) { this.elementType = elementType; // 初始化链表结构(头、尾节点置空,大小设为0等) } // 其他链表操作方法(add、remove等)保持不变 }
2. 重写equals方法
在equals方法中,先判断对象类型,再直接比较存储的elementType,类型不匹配直接返回false,之后再比较链表的大小和元素内容:
@Override public boolean equals(Object obj) { // 引用相同直接返回true if (this == obj) return true; // 不是MyDoublyLinkedList实例直接返回false if (!(obj instanceof MyDoublyLinkedList<?> otherList)) return false; // 先比较元素类型,类型不同直接判定不相等 if (!this.elementType.equals(otherList.elementType)) { return false; } // 大小不同直接不相等 if (this.size() != otherList.size()) { return false; } // 遍历比较每个元素 Node<E> current = this.head; Node<?> otherCurrent = otherList.head; while (current != null) { E elem1 = current.item; Object elem2 = otherCurrent.item; // 处理null元素的情况 if (elem1 == null ? elem2 != null : !elem1.equals(elem2)) { return false; } current = current.next; otherCurrent = otherCurrent.next; } return true; }
3. 同步重写hashCode方法
根据Java规范,equals方法重写后必须同步重写hashCode方法,保证相等的对象具有相同的哈希值,这里要把elementType的哈希值纳入计算:
@Override public int hashCode() { int result = elementType.hashCode(); result = 31 * result + this.size(); Node<E> current = this.head; while (current != null) { result = 31 * result + (current.item == null ? 0 : current.item.hashCode()); current = current.next; } return result; }
为什么ArrayList会认为空的不同泛型链表相等?
因为Java泛型擦除后,ArrayList<String>和ArrayList<Integer>在运行时都是ArrayList类型,而ArrayList的equals方法只检查元素是否逐一相等,空链表没有元素可比较,所以会返回true。我们通过手动存储元素类型,就能在equals时区分不同泛型的空链表。
内容的提问来源于stack exchange,提问作者sfeng
相关产品推荐
相关产品推荐

