假设我正在实现一个分类集合(简单示例 - a Set 基于排序的数组。)考虑此(不完整的)实现:

import java.util.*;

public class SortedArraySet<E> extends AbstractSet<E> {

    @SuppressWarnings("unchecked")
public SortedArraySet(Collection<E> source, Comparator<E> comparator) {
    this.comparator = (Comparator<Object>) comparator;
    this.array = source.toArray();
    Arrays.sort(this.array, this.comparator);
}

@Override
public boolean contains(Object key) {
    return Arrays.binarySearch(array, key, comparator) >= 0;
}

    private final Object[] array;

    private final Comparator<Object> comparator;

}

现在让我们创建一组整数

Set<Integer> s = new SortedArraySet<Integer>(Arrays.asList(1, 2, 3), null);

并测试它是否包含一些特定值:

System.out.println(s.contains(2));
System.out.println(s.contains(42));
System.out.println(s.contains("42"));

上面的第三行将抛出 ClassCastException. 。不是我想要的。我希望它能返回 false (作为 HashSet 做。)

我可以通过捕获异常并返回错误来获得这种行为:

@Override    
public boolean contains(Object key) {
    try {
        return Arrays.binarySearch(array, key, comparator) >= 0;
    } catch (ClassCastException e) {
        return false;
    }
}

假设 source 收集正确键入, ,如果我这样做会怎么办?

有帮助吗?

解决方案

我认为这没有任何问题作为Javadoc Collection.contains 显然指出扔 ClassCastException是可选的。

唯一的 问题 我知道是如果您有错误 某处 不抛出例外会阻止您确定它。

其他提示

TreeSet 班级确实扔了 ClassCastException 对于不兼容的论点 contains() (不兼容 Comparator 该集合使用)。因此,抛出该例外没有错。只需确保您记录这可能会发生。

让CCE从contains()扔掉是完全合法的。但是,许多收集实现都会抓住并返回错误,我认为这也是完全合法的,实际上是更友好的行为。

在equals()中,您没有选择;您必须抓住该CCE。

抓住不受限制的例外应该总是感到肮脏,但有时候这是正确的事情。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top