使用一组对时ClassCastException

时间:2018-06-15 11:03:47

标签: java set treeset

我想在Java中使用一组对,但是当我调用contains()以查看它是否已包含特定对时,我总是得到ClassCastException。有没有办法避免这种行为?

它实例化如下:

private static final Set<Pair<String, String>> BLACKLIST = new TreeSet<>();

BLACKLIST.add(new Pair<String, String>("anytext", "anytext"));

调用contains()会导致以下ClassCastException:

if (!blacklist.contains(new Pair<String, String>(localizedFile.getName(), key)))

java.lang.ClassCastException: .common.util.Pair cannot be cast to java.lang.Comparable
        at java.util.TreeMap.compare(TreeMap.java:1294)
        at java.util.TreeMap.put(TreeMap.java:538)
        at java.util.TreeSet.add(TreeSet.java:255)

我使用的是java.util类而不是我自己的类。是否有一种优雅的方法可以避免实现一个重载common.util.Pair的新类对?

2 个答案:

答案 0 :(得分:1)

TreeSet使用其元素的natuarl排序 除非在创建Set时将任何显式比较器传递给构造函数。

合同说明插入了所有元素 该集必须实现Comparable接口。此外,所有这些元素必须是可相互比较的e1.compareTo(e2)一定不能抛出 集合中任何元素e1和e2的ClassCastException。

您的代码是

  private static final Set<Pair<String, String>> BLACKLIST = new TreeSet<>();
BLACKLIST.add(new Pair<String, String>("anytext", "anytext"));

由于你没有将一个显式的Comparator传递给构造函数,并且你的元素(Pair)都没有实现一个好的Comparable,你在向该集合中添加一个元素时会得到一个类转换异常。

我的建议是   (i)通过一个明确的比较器

或(ii)使Pair实现Comparable,如下所示

public class Pair<T1 extends Comparable<T1>, T2 extends Comparable<T2>> implements Comparable<Pair<T1, T2>> {
    T1 firstName;
    T2 secondName;

    public Pair(T1 firstName, T2 secondName) {
        this.firstName = firstName;
        this.secondName = secondName;
    }

    public T1 getFirstName() {
        return firstName;
    }

    public T2 getSecondName() {
        return secondName;
    }

    // elements ordered with first parameter .you can make a better
    // comparable as well
    @Override
    public int compareTo(Pair<T1, T2> o) {
        // TODO Auto-generated method stub
        return this.firstName.compareTo(o.firstName);
    }

}

答案 1 :(得分:0)

TreeSet使用其元素的自然顺序,似乎要转换为Comparable来执行此操作。

您可以采取的措施是让TreeSet成为您自己的Comparator所以它可以使用它代替自然排序。

Set<Pair<String, String>> blacklist = new TreeSet<>(
    Comparator.comparing(Pair::getFirst)
              .thenComparing(Pair::getSecond));

将先按Pair

的第二项排序