如何修复TreeSet中的java.lang.ClassCastException?
TreeSet是Java集合框架中的一个泛型类,它实现了SortedSet接口。它以树形结构存储集合的元素。此外,所有元素都以排序的方式存储,如果我们尝试添加自定义类对象,则这些元素必须可以相互比较,否则我们将遇到java.lang.ClassCastException。这里,自定义类对象是指使用构造函数创建的用户定义对象。为了修复TreeSet中的ClassCastException,我们可以使用Comparator接口或Comparable接口。让我们详细讨论一下。
TreeSet的一般语法如下所示
语法
TreeSet<TypeOfSet> nameOfSet = new TreeSet<>();
修复TreeSet中的java.lang.ClassCastException
在本节中,我们将解释如何使用Comparator和Comparable接口来修复TreeSet中的ClassCastException。让我们从一个示例程序开始讨论,该程序将向我们展示ClassCastException。
示例1
在下面的示例中,我们将尝试在没有Comparator和Comparable的情况下将自定义类对象添加到TreeSet,以显示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
顾名思义,它用于比较某些东西。在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”。
然后,定义另一个实现Comparator接口的类“Comp”,并在其中使用“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”。在其中,声明两个变量并定义该类的构造函数以及分别为字符串和整数类型的两个参数“item”和“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以及如何修复此异常。