1

我正在寻找一种java.util.Queue实现或工厂方法,它为我提供了一种Queue默默丢弃null元素的方法。

java.util.LinkedList不是一个解决方案,因为它允许对元素进行排队 和取消排队(...应该向前取消排队,直到它为空或在头部位置有一个 -null 元素)不是解决方案,因为它在尝试添加元素时抛出。null nullQueuenon
java.util.ArrayDequeNullPointerExceptionnull

应该可以Queue用现有的Queue(现有的Queue可能包含null被新构建Queue的操作删除的元素)构建这样的 a。

是否已经有一个强大的解决方案?

4

2 回答 2

3

虽然我意识到这并不能直接回答您的问题,但如果您找不到实现并决定创建自己的课程,则此答案应该适用。

由于子类不符合超类的预期实现和使用(例如 super 可能依赖于能够添加 null 元素,因此这会破坏它),我会不鼓励按照“Hot Licks”的建议进行子类化。此外,您通过更改主要实现细节来打破 Is-A 原则。

我建议您使用组合,通过自己的方法提供适当的方法,这可能会在必要时改变行为。

在Effective Java的第 16 章中阅读更多内容。

于 2013-02-20T01:14:22.757 回答
1

没有理由必须创建一个全新的子类,您可以在创建实例时覆盖所需的方法。

这是一个例子:

final ArrayDeque<String> nonNullDeque = new ArrayDeque<String>() {
    @Override
    public void addFirst(final String s) {
        if (s != null) { super.addFirst(s); }
    }

    @Override
    public boolean add(final String s) {
        return s != null && super.add(s);
    }

    @Override
    public void addLast(final String s) {
        if (s != null) { super.addLast(s); }
    }
};

这就是你有能力用你自己的行为覆盖方法的全部原因,超类的内部工作应该是一个黑匣子,你与它的约定是接受参数并返回其接口支持的结果,不支持其内部运作。

就我个人而言,我会更进一步,而不是使用Google findbugs library@Nonnull检查空值并使用 JSR=305注释。注释不仅会在你的代码有机会之前捕捉到,它还隐含地记录了你的意图是什么。null

public void addFirst(@Nonnull final String s) {
    if (s != null) { super.addFirst(s); }
}

Maven 依赖项位于 Central Repo 中,因此可以轻松添加到您的项目中。

<dependency>
    <groupId>com.google.code.findbugs</groupId>
    <artifactId>jsr305</artifactId>
    <version>2.0.1</version>
</dependency>
于 2013-02-20T01:25:10.817 回答