You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Deque实现:ArrayDeque与LinkedListDeque的equals方法问题排查

自定义Deque的equals方法问题:ArrayDeque与LinkedListDeque相等性测试失败

我正在实现自定义Deque接口,除equals方法外其余功能均正常。提交代码到自动检查器时,相等性测试失败,提示**"元素相同的ArrayDeques和LinkedListDeques应相等"**,找不到问题所在。

LinkedListDeque的equals方法实现

/** Returns whether the parameter o is equal to the Deque.
 * o is considered equal if it is a Deque and if it contains
 * the same contents (as governed by the generic T's equals method) in the same order. */
 
@Override
public boolean equals(Object o) {
    if (o == null) {
        return false;
    }
    if (o == this) {
        return true;
    }
    if (!(o instanceof Deque)) {
        return false;
    }

    if (o instanceof LinkedListDeque) {
        LinkedListDeque<T> other = (LinkedListDeque<T>) o;
        if (this.size() != other.size()) {
            return false;
        }
        Iterator<T> dequeIt = this.iterator();
        Iterator<T> otherIt = other.iterator();
        while (dequeIt.hasNext()) {
            if (!dequeIt.next().equals(otherIt.next())) {
                return false;
            }
        }
        return true;
    } else if (o instanceof ArrayDeque) {
        ArrayDeque<T> other = (ArrayDeque<T>) o;
        if (this.size() != other.size()) {
            return false;
        }
        Iterator<T> thisIt = iterator();
        Iterator<T> otherIt = other.iterator();
        while (thisIt.hasNext()) {
            if (!thisIt.next().equals(otherIt.next())) {
                return false;
            }
        }
        return true;
    }
    return false;
}

ArrayDeque的equals方法实现

@Override
public boolean equals(Object o) {
    if (o == null) {
        return false;
    }
    if (this == o) {
        return true;
    }
    if (!(o instanceof Deque)) {
        return false;
    }
    if (o instanceof ArrayDeque) {
        ArrayDeque<T> other = (ArrayDeque<T>) o;
        if (other.size() != this.size) {
            return false;
        }
        Iterator<T> thisIt = iterator();
        Iterator<T> otherIterator = other.iterator();
        while (thisIt.hasNext()) {
            if (!thisIt.next().equals(otherIterator.next())) {
                return false;
            }
        }
        return true;
    } else if (o instanceof LinkedListDeque) {
        LinkedListDeque<T> other = (LinkedListDeque<T>) o;
        if (other.size() != this.size) {
            return false;
        }
        Iterator<T> thisIt = iterator();
        Iterator<T> otherIterator = other.iterator();
        while (thisIt.hasNext()) {
            if (!thisIt.next().equals(otherIterator.next())) {
                return false;
            }
        }
        return true;
    }
    return false;
}

我的单元测试(已通过)

@Test
public void randomizedInsertionAndDeletion(){
    ArrayDeque<Integer> deque = new ArrayDeque<>();
    LinkedListDeque<Integer> deque2 = new LinkedListDeque<>();
    int N = 5000;
    for (int i =0; i<N; i++) {
        int operationNumber = StdRandom.uniform(0, 4);
        int randValue = StdRandom.uniform(0, 100);
        if (operationNumber == 0) {
            deque.addFirst(randValue);
            deque2.addFirst(randValue);
            assertEquals((Integer) randValue, deque.removeFirst());
            assertEquals((Integer) randValue, deque2.removeFirst());
        } else if (operationNumber == 1) {
            deque.addLast(randValue);
            deque2.addLast(randValue);
            assertEquals((Integer) randValue, deque.removeLast());
            assertEquals((Integer) randValue, deque2.removeLast());
        } else if (operationNumber == 2) {
            assertEquals(deque.get(0), deque.removeFirst());
            assertEquals(deque2.get(0), deque.removeFirst());
        } else if (operationNumber == 3) {
            assertEquals(deque.removeLast(), deque.get(deque.size()));
        } else if (operationNumber == 4) {
            boolean actual1 = deque.equals(deque2);
            boolean actual2 = deque2.equals(deque);
            assertEquals(true, actual1);
            assertEquals(true, actual2);
        }
    }
}

@Test
public void equals() {
    ArrayDeque<Boolean> deque = new ArrayDeque<>();
    deque.addLast(true);
    deque.addFirst(false);
    deque.addFirst(false);
    deque.addFirst(true);

    LinkedListDeque<Boolean> deque2 = new LinkedListDeque<>();
    deque2.addLast(true);
    deque2.addFirst(false);
    deque2.addFirst(false);
    deque2.addFirst(false);

    assertEquals(false, deque2.equals(deque));
    assertEquals(false, deque.equals(deque2));
}

问题分析与修复方案

问题出在ArrayDeque的equals方法中直接访问了size成员变量,而不是调用size()方法。LinkedListDeque的equals里用的是this.size(),而ArrayDeque里用的是this.size,如果你的ArrayDeque中size成员变量没有在add/remove操作时正确同步更新(比如size()方法是通过计算数组头尾指针得到实际大小,而非直接返回size成员变量),就会导致size比较错误,即使元素完全一致也会返回false。

修改ArrayDeque的equals方法,将所有this.size替换为this.size():

// 第一处修改
if (other.size() != this.size()) {
    return false;
}

// 第二处修改
if (other.size() != this.size()) {
    return false;
}

这样就能保证size比较的是实际元素数量,和LinkedListDeque的逻辑保持一致,通过相等性测试。

内容的提问来源于stack exchange,提问作者bobcob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 09:12:00