Java 如何在TreeSet中修复java.lang.ClassCastException错误
The TreeSet是Java Collection Framework的泛型类,实现了SortedSet接口。它将集合的元素存储在树结构中。此外,所有元素都按排序方式存储,如果我们尝试添加自定义类对象,它们必须是相互可比较的,否则我们会遇到java.lang.ClassCastException错误。这里,自定义类对象指的是使用构造函数创建的用户定义对象。为了修复TreeSet中的ClassCastException错误,我们可以使用Comparator接口或Comparable接口。让我们详细讨论一下它们。
TreeSet的一般语法如下:
语法:
TreeSet<TypeOfSet> nameOfSet = new TreeSet<>();
修复TreeSet中的java.lang.ClassCastException
在这个部分中,我们将解释如何使用Comparator和Comparable接口来修复TreeSet中的ClassCastException。让我们从一个示例程序开始,它将展示给我们ClassCastException。
示例1
在下面的示例中,我们将尝试向TreeSet添加自定义类对象,没有使用Comparator和Comparable,以展示Java编译器抛出java.lang.ClassCastException的情况。
import java.util.*;
public class ShopBag {
String item;
int price;
ShopBag(String item, int price) { // constructor
// this keyword shows these variables belong to constructor
this.item = item;
this.price = price;
}
public static void main(String[] args) {
// Declaring collection TreeSet
TreeSet<ShopBag> trSet = new TreeSet<ShopBag>();
// Adding object to the collection
trSet.add(new ShopBag("Rice", 59));
trSet.add(new ShopBag("Milk", 60));
// to print the objects
for (ShopBag print : trSet) {
System.out.println("Item: " + print.item + ", " + "Price: " + print.price);
}
}
}
输出
Exception in thread "main" java.lang.ClassCastException: class ShopBag cannot be cast to class java.lang.Comparable (ShopBag is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')
at java.base/java.util.TreeMap.compare(TreeMap.java:1569)
at java.base/java.util.TreeMap.addEntryToEmptyMap(TreeMap.java:776)
at java.base/java.util.TreeMap.put(TreeMap.java:785)
at java.base/java.util.TreeMap.put(TreeMap.java:534)
at java.base/java.util.TreeSet.add(TreeSet.java:255)
at ShopBag.main(ShopBag.java:14)
如何使用Comparator修复java.lang.ClassCastException错误
首先,让我们介绍一下Comparator接口。
Comparator
顾名思义,Comparator用于比较两个对象。在Java中,Comparator是一个用于对自定义对象进行排序的接口。我们可以在它的内置方法 compare() 中编写自己的逻辑来排序指定的对象。这个方法接受两个对象作为参数,并返回一个整数值。通过这个整数值,Comparator决定哪个对象更大。
语法
class nameOfComparator implements Comparator< TypeOfComparator >() {
compare( type object1, type object2 ) {
// logic for comparison
}
}
示例2
以下示例说明了在修复ClassCastException中使用Comparator的用法。
方法
- 首先,导入’java.util’包以便我们可以使用TreeSet。
-
创建一个名为’ShopBag’的类。在其中,声明两个变量,并定义一个该类的构造函数,它有两个参数,分别为类型为字符串和整数的’item’和’price’。
-
然后,定义另一个名为’Comp’的类,它实现了Comparator接口,并在其中使用’compare()’方法来按升序排序TreeSet。
-
在’main()’方法中,通过传递’Comp’类的实例来创建一个TreeSet集合,以便它可以被排序。
-
最后,使用’add()’方法将一些元素存储到TreeSet集合中,并使用for-each循环打印集合的元素。
import java.util.*;
class ShopBag {
String item;
int price;
ShopBag(String item, int price) { // constructor
// this keyword shows these variables belong to constructor
this.item = item;
this.price = price;
}
}
// use of comparator interface
class Comp implements Comparator<ShopBag> {
// logic to sort
public int compare(ShopBag i, ShopBag j) {
if(i.price > j.price) { // performing comparison
return 1;
} else {
return -1;
}
}
}
public class Example2 {
public static void main(String[] args) {
// Declaring collection TreeSet
TreeSet<ShopBag> trSet = new TreeSet<ShopBag>(new Comp());
// Adding object to the collection
trSet.add(new ShopBag("Rice", 59));
trSet.add(new ShopBag("Milk", 60));
trSet.add(new ShopBag("Bread", 45));
trSet.add(new ShopBag("Peanut", 230));
trSet.add(new ShopBag("Butter", 55));
System.out.println("Objects of the collection: ");
// to print the objects
for (ShopBag print : trSet) {
System.out.println("Item: " + print.item + ", " + "Price: " + print.price);
}
}
}
输出
Objects of the collection:
Item: Bread, Price: 45
Item: Butter, Price: 55
Item: Rice, Price: 59
Item: Milk, Price: 60
Item: Peanut, Price: 230
如何使用Comparable接口修复java.lang.ClassCastException
让我们从介绍Comparable接口开始讨论。
Comparable接口
当我们想要按照自然顺序对自定义对象进行排序时,这个接口非常有用。例如,它对字符串按照字典顺序排序,对数字按照数值顺序排序。此接口位于’java.lang’包中。
语法
class nameOfclass implements Comparable<nameofclass>
在这里,class是创建一个类的关键字,implements是启用接口提供的功能的关键字。
compareTo()
Comparable接口只定义了一个名为CompareTo的方法,可以重写该方法来对对象集合进行排序。它给了类比较对象的能力。当’this’对象等于传递的对象时,它返回0;如果’this’对象大于传递的对象,则返回正值;否则返回负值。
语法
compareTo(nameOfclass nameOfobject);
示例3
以下示例演示了在修复ClassCastException中使用Comparable的方法。
方法
- 首先,导入’java.util’包,以便我们可以使用TreeSet进行操作。
-
创建一个实现Comparable接口的类’ShopBag’。在其中,声明两个变量,并定义该类的构造函数,其中包括两个参数’tem’和’price’,分别为字符串和整数类型。
-
定义’compareTo’方法,其中一个参数是类’ShopBag’的对象,用于比较’this’对象和新创建的对象。
-
现在,在main()方法中,声明一个名为’trSet’的对象,该对象是TreeSet类型的’ShopBag’类的集合,使用一个名为’add()’的内置方法将对象的详细信息存储到集合中。
-
使用for-each循环打印集合的元素。
import java.util.*;
public class ShopBag implements Comparable<ShopBag> {
String item;
int price;
ShopBag(String item, int price) { // constructor
// this keyword shows these variables belong to constructor
this.item = item;
this.price = price;
}
// overriding method
public int compareTo(ShopBag comp) {
if(this.price > comp.price) { // performing comparison
return 1;
} else {
return -1;
}
}
public String toString() {
return "Item: " + this.item + ", Price: " + this.price;
}
public static void main(String[] args) {
// Declaring collection TreeSet
TreeSet<ShopBag> trSet = new TreeSet<ShopBag>();
// Adding object to the collection
trSet.add(new ShopBag("Rice", 59));
trSet.add(new ShopBag("Milk", 60));
trSet.add(new ShopBag("Bread", 45));
trSet.add(new ShopBag("Peanut", 230));
trSet.add(new ShopBag("Butter", 55));
System.out.println("Objects of the collection: ");
// to print the objects
for (ShopBag print : trSet) {
System.out.println("Item: " + print.item + ", " + "Price: " + print.price);
}
}
}
输出
Objects of the collection:
Item: Bread, Price: 45
Item: Butter, Price: 55
Item: Rice, Price: 59
Item: Milk, Price: 60
Item: Peanut, Price: 230
结论
我们通过定义TreeSet和介绍TreeSet的ClassCastException来开始本文。在接下来的部分中,我们介绍了Comparator和Comparable接口,这些接口在修复ClassCastException时非常有帮助。然后,我们讨论了三个示例程序,展示了ClassCastException的情况以及如何修复此异常。