我收到 ClassCastException 错误。当我插入从我创建的类派生的对象时,会发生此错误。我的代码如下:当我运行时,我总是收到ClassCastException错误。此外,我的类的比较器在调试器中显示为 null。
我已经编写了一个比较器(据我所知)并覆盖了必要的方法。
如何将 Set<> 与我创建的类一起使用并使用 contains() 方法?
public class Person implements Comparable<Person>
{
int age;
double height;
public Person(int age, double height)
{
this.age = age;
this.height = height;
}
@Override
public int compareTo(Person person)
{
return age - person.age;
}
public boolean equals(Object obj)
{
final Person other = (Person) obj;
if (this.age == other.age)
return true;
return false;
}
public static void main(String[] args)
{
Set<Person> people = new HashSet<>();
Person p1 = new Person(10, 1.00);
Person p2 = new Person(11, 1.10);
Person p3 = new Person(12, 1.20);
Person p4 = new Person(14, 1.40);
people.add(p1);
people.add(p2);
people.add(p3);
people.add(p4);
if(people.contains(12))
System.out.println("contains");
else
System.out.println("does not contain");
}
}
我已经设法摆脱了这个错误。但是现在,输出是"不包含"。
我将要建议的内容与 ClassCastException 无关,它被抛出只是因为您正在对一组类型 Person
的对象进行int
参数检查contains
......简短回答:不能将对象强制转换为它不是实例的子类。甚至javadoc也正是这样说的。
对于这种情况,我真的很喜欢使用番石榴谓词。谓词允许您将布尔条件应用于任何可迭代对象,并返回满足指定条件的元素。在您的示例中,您可以定义谓词,以返回您想要的任何年龄的人员的子集。
Predicate<Person> getAgePredicate(final int age) {
return new Predicate<Person>() {
public boolean apply(Person p) { return p.age == age; }
};
}
Set<Person> people = new Hashset<>();
... // populate people
Set<Person> peopleOfAgeTwelve = Sets.filter(people, getAgePredicate(12));
希望这有帮助。
我假设您的类Adjacent
基于您的代码实现Comparable
接口。你的类包含一个名为 getID()
的方法。因此,当您重写 compareTo()
方法时,您希望确保对象比较有意义。我不确定你的getID()
会得到什么回报。但它似乎是整数。因此,您可能希望更改compareTo()
的实现,如下所示:
@Override
public int compareTo(Adjacent adj) {
return this.getId() - adj.getId();
}
因此,这样比较将返回负/零/正,具体取决于两个Adjacent
类对象的 ID 比较。
同样在重写的 equals()
方法中,实现不正确,因为即使两个对象具有相同的哈希代码,它们也不一定相等。覆盖equals
和hashCode
方法的一个很好的例子在另一个SO帖子中给出。另外,在您的情况下,我认为您可能甚至不需要覆盖equals
方法,因为您的类已经实现了Comparable
接口。
不要使用不同类型的参数调用 contain;此行为实际上已记录在案。由于传统原因,contains()
方法是一种非通用方法,如果您使用的是 TreeSet
,则不安全。如果您实施hashCode()
和equals()
并切换到HashSet
,您的问题就会消失。
你真的需要按年龄排序的人吗?
编辑:我现在明白你想做什么了。你不想要一个Set
,你想要Map<Integer, Collection<Person>>
,或者只是一个循环来寻找给定的年龄。
for (Person p : people) {
if (p.age == 12) ...;
}
或
Map<Integer, Set<Person> peopleByAge = new HashMap<Integer, Set<Person>>();
for (Person p : people) {
if (!peopleByAge.contains(p.age)) {
peopleByAge.put(p.age, new TreeSet<Person>();
}
peopleByAge.get(p.age).add(p);
}
if (people.age.containsKey(12)) ...