如何在Java中使用自定义比较器修复TreeSet中的java.lang.ClassCastException?


TreeSet是Java集合框架的一个泛型类,它实现了SortedSet接口。它以树形结构存储集合的元素。此外,所有元素都以排序的方式存储,如果我们尝试添加自定义类对象,则这些元素必须相互可比较,否则我们会遇到java.lang.ClassCastException。这里,自定义类对象是指使用构造函数创建的用户定义的对象。解决此ClassCastException的一种方法是使用自定义比较器。让我们详细讨论一下。

TreeSet的一般语法如下所示

语法

TreeSet<TypeOfSet> nameOfSet = new TreeSet<>(); 

使用比较器修复TreeSet中的java.lang.ClassCastException

在本节中,我们将解释如何使用自定义比较器来修复TreeSet中的ClassCastException。让我们从比较器开始讨论。

比较器

顾名思义,它用于比较某些东西。在Java中,Comparator是一个接口,用于排序自定义对象。我们可以在其内置方法“compare()”中编写我们自己的逻辑来排序指定的对象。此方法将两个对象作为参数,然后返回一个整数值。通过这个整数值,Comparator决定哪个对象更大。

语法

class nameOfComparator implements Comparator< TypeOfComparator >() {
	compare( type object1, type object2 ) {
		// logic for comparison
	}
}  

这里,class是创建类的关键字,implements是启用使用接口提供的功能的关键字。

示例1

在下面的示例中,我们将尝试在没有比较器的情况下将自定义类对象添加到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)

示例2

下面的示例说明了使用比较器修复ClassCastException的方法。

方法

  • 首先,导入'java.util'包,以便我们可以使用TreeSet。

  • 创建一个类'ShopBag'。在其中,声明两个变量并定义此类的构造函数以及两个参数'item'和'price',类型分别为字符串和整数。

  • 然后,定义另一个类'Comp',它实现了Comparator接口,并在其中使用'compare()'方法将TreeSet按升序排序。

  • 在'main()'方法中,通过传递'Comp'类的实例来创建一个TreeSet集合,以便它可以被排序。

  • 最后,使用'add()'方法将一些元素存储到TreeSet集合中,然后使用foreach循环打印集合的元素。

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) {
         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

结论

我们首先定义了TreeSet并介绍了TreeSet的ClassCastException。在下一节中,我们介绍了Comparator接口,它可以帮助修复ClassCastException。然后,我们讨论了两个示例程序,它们显示了ClassCastException以及如何修复此异常。

更新于:2023年7月20日

浏览量:118

启动你的职业生涯

完成课程获得认证

开始学习
广告
© . All rights reserved.