这是适合这种情况的设计吗?

时间:2015-01-17 19:19:41

标签: java eclipse list sorting compareto

我在未排序的链表和排序的链表中实现了remove(Object o)方法。这两个类都扩展了AbstractLinkedList(代码重用)

这是我在未排序链表中删除(对象o)的代码

@Override
public void remove(E value) {
    if(front != null) {
        if(front.data.equals(value)) {
            front = front.next;
        } else {
            ListNode<E> current = front;
            boolean hasRemovedElement = false;
            while(current.next != null && !hasRemovedElement) {
                if(current.next.data.equals(value)) {
                    current.next = current.next.next;
                    hasRemovedElement = true;
                }
                current = current.next;
            }
        }
    }
}

我的代码是在排序链表中删除(对象o)

public void remove(E value) {
    if(front != null) {
        ListNode<E> current = front;
        if(front.data.equals(value)) {
            front = front.next;
        } else {
            boolean hasRemovedElement = false;
            while(current.next != null && !hasRemovedElement 
                    && current.next.data.compareTo(value) >= 0) {
                if(current.next.data.equals(value)) {
                    current.next = current.next.next;
                    hasRemovedElement = true;
                }
                current = current.next;
            }
        }
    }

我立刻注意到的是我的两种方法中的代码几乎完全相同。排序链接列表中的remove(Object o)只有一个条件检查,说明如果下一个元素小于您尝试删除的值,则您尝试删除的元素无法在列表中找到。我利用代码重用做的是在AbstractLinkedList中实现两个列表都可以调用的重载版本,即

@Override
protected void remove(E value, E toCheckAgainst) {
    if(front != null) {
        ListNode<E> current = front;
        if(front.data.equals(value)) {
            front = front.next;
        } else {
            boolean hasRemovedElement = false;
            while(current.next != null && !hasRemovedElement 
                    && current.next.data.compareTo(toCheckAgainst) >= 0) {
                if(current.next.data.equals(value)) {
                    current.next = current.next.next;
                    hasRemovedElement = true;
                }
                current = current.next;
            }
        }
    }

在未分类的链表中

@Override
public void remove(E value) {
      remove(value, CHECKER)
}

但我的问题是我应该如何在未排序的链表中创建这个CHECKER?就排序链表而言,此检查器可能只是值。如果您的值小于检查器(已排序),则检查器的角色基本上是停止迭代。我可以使检查器对未排序的链表没有任何影响有什么价值?我尝试使用像MIN POSSIBLE = -9999999之类的int,但你不能将int与泛型进行比较。或者它在设计方面更好,只是在两个类中都有相同的实现。

1 个答案:

答案 0 :(得分:0)

我建议将这些方法保留原样。代码重用应该与可读性等进行权衡。

但是假设你想要这样做,我会使用一种测试程序(或者在Java 8中,Predicate)。你在超类中声明了这样的接口:

protected interface Tester<E> {
    public boolean test(E testObj);
}

然后你的一般删除方法是:

protected void remove(E value, Tester<E> extraCondition) {
    if(front != null) {
        ListNode<E> current = front;
        if(front.data.equals(value)) {
            front = front.next;
        } else {
            boolean hasRemovedElement = false;
            while(current.next != null && !hasRemovedElement 
                    && extraCondition.test(current.next.data) {
                if(current.next.data.equals(value)) {
                    current.next = current.next.next;
                    hasRemovedElement = true;
                }
                current = current.next;
            }
        }
    }
}

然后在未分类的列表中,您有:

@Override
public void remove(final E value) {
    remove(value, new Tester<E>() {
        public boolean test(E testObj) {
            return true;
        }
    });
}

在您的排序列表中:

public void remove(final E value) {
    remove(value, new Tester<E>() {
        public boolean test(E testObj) {
            return testObj.compareTo(value) >= 0;
        }
    });
}

因此,在未排序的列表中,您传递的条件始终返回true,并且在排序列表中,您传递的条件是基于与值的比较返回true。

你想要测试null然后才进行比较会有效,但是:

  • 这使它更难以理解。
  • 它仅适用于此特定情况。如果您有一个按降序排序的列表怎么办?或者有一些奇特的东西,如特殊的&#34;停止&#34;元素,只允许您删除&#34;停止&#34;之前的元素。元件?

一般情况下,不要在超类中放置仅与您当前可以想到的子类相关的专门行为,只是为了在子类中保存一些编码。