使用一组对时出现 ClassCastException
ClassCastException when using a set of pairs
我想在 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 classes 而不是我自己的。有没有一种优雅的方法来避免实现一个新的 class 对重载 common.util.Pair?
TreeSet
使用其元素的自然顺序,它似乎转换为 Comparable
来做到这一点。
要使此代码正常工作,您可以为 TreeSet
提供您自己的 Comparator
,这样它就可以使用它而不是自然排序。
Set<Pair<String, String>> blacklist = new TreeSet<>(
Comparator.comparing(Pair::getFirst)
.thenComparing(Pair::getSecond));
这将按 Pair
的第一项,然后是第二项排序。
TreeSet 使用其元素的自然排序
除非您在创建 Set 时将任何显式比较器传递给构造函数。
合约说所有元素都插入
该集合必须实现 Comparable interface.Furthermore,所有此类元素必须相互比较 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,因此您在向集合中添加元素时会遇到 class 转换异常。
我的建议是
(i) 通过显式比较器
或(ii)使Pair implements 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);
}
}
我想在 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 classes 而不是我自己的。有没有一种优雅的方法来避免实现一个新的 class 对重载 common.util.Pair?
TreeSet
使用其元素的自然顺序,它似乎转换为 Comparable
来做到这一点。
要使此代码正常工作,您可以为 TreeSet
提供您自己的 Comparator
,这样它就可以使用它而不是自然排序。
Set<Pair<String, String>> blacklist = new TreeSet<>(
Comparator.comparing(Pair::getFirst)
.thenComparing(Pair::getSecond));
这将按 Pair
的第一项,然后是第二项排序。
TreeSet 使用其元素的自然排序 除非您在创建 Set 时将任何显式比较器传递给构造函数。
合约说所有元素都插入
该集合必须实现 Comparable interface.Furthermore,所有此类元素必须相互比较 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,因此您在向集合中添加元素时会遇到 class 转换异常。
我的建议是 (i) 通过显式比较器
或(ii)使Pair implements 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);
}
}