Java Collection <t> remove()</t>

时间:2012-10-22 22:15:51

标签: java generics collections

为什么在Collection<T>中,方法布尔remove(Object o)未定义为boolean remove(T o)

当我有Collection<String> list我确定我不想做list.remove(new Date())时。

编辑:已解决:Why aren't Java Collections remove methods generic?

问题2:

当我上课时:

class Value {
   Object getValue() {
   // return something;
   }
}

然后我想实现一个新的酷列表:

class CoolList<T extends Value> implements Collection<T> {
    // ...

    @Override
    public boolean remove(Object o) {
        try {
           T value = (T) o; // I mean the cast here
               removeInternal(value);
        } catch (ClassCastException e) {
           return false;
        }
    }
}

如何在不发出警告(未经检查的演员表)且不使用@SuspressWarning的情况下进行清理演员,这是否可能?

编辑: 在内部我希望列表能够恢复已删除的项目,因此我在内部有一个List<T> deletedItems。 因此,removeInternal()方法将要删除的项目附加到内部deletedItems列表,然后删除它,因此我需要某种类型的转换。

谢谢。

3 个答案:

答案 0 :(得分:2)

关于你的第二个问题:只使removeInternal非通用。它应该使用与第一个问题的答案中描述的逻辑相同的逻辑:removeInternal(o)删除对象e,使(o==null ? e==null : o.equals(e))为真。 (如果您实现的逻辑与此不相等,则违反了Collection接口的合同。)不需要通用removeInternal

编辑以下是一个如何实现非通用removeInternal的示例:

private boolean removeInternal(Object o) {
    for (int i = 0; i < currentSize; ++i) {
        T elt = get(i);
        if (o == null ? elt == null : o.equals(elt)) {
            removeElementAtPosition(i);
            deletedItems.add(elt);
            return true;
        }
        return false;
    }
}

这假设removeElementAt(int)会将i th 项目正确转移到deletedItems并调整项目的内部计数。重要的是要注意,被删除的元素不一定是与参数中传递的对象相同;它只是满足等式谓词的第一个元素。

答案 1 :(得分:0)

您无法像这样转换为通用类型T。在这种情况下,将使用最具体的已知类型,例如Value

您可以做的是在集合构造函数中传递Class<T>类型的参数,然后使用class.cast()转换值。这不会产生未经检查的强制转换警告,但与示例中的代码一样不安全。

答案 2 :(得分:0)

这是不可能的,但即使是这样,你也不应该这样做。

如果项目与其他项目相同,则应删除该项目。故意不要求它是同一类型,所以你应该检查它是否等于然后删除 - 与它的类型无关。