Java TreeSet排序报MyComparator1已存在及空指针异常排查
问题说明
代码目标是通过Comparable接口实现Employee类按工号的默认排序,通过Comparator接口实现按姓名字母序的定制排序,在TreeSet中验证排序效果时出现两类错误:
- 编译期提示
the type MyComparator1 already exists错误 - 运行时抛出
NullPointerException空指针异常
问题根因
类重名报错原因
Java语法规定同一个包路径下不允许存在同名的顶层类,出现该报错说明CollectionsPkg包下已经存在一个名为MyComparator1的类,和当前定义的比较器类重名,编译器检测到命名冲突就会抛出该错误。
空指针异常原因
空指针的核心问题出在Employee类的构造方法赋值逻辑写反了:
// 原错误写法 Employee(int eid,String ename){ eid=this.eid; ename=this.ename; }
这段代码是把对象成员变量的默认值(int类型eid默认值为0,String类型ename默认值为null)赋值给方法传入的形参,根本没有给实例的属性赋值。所有创建出来的Employee实例ename属性都是null,后续比较时调用null.compareTo()就会触发空指针,同时所有实例的eid都是0,默认排序逻辑也会完全失效。
修复步骤
- 解决类重名问题:要么删除
CollectionsPkg包下已有的重名MyComparator1.java文件,要么将当前自定义的比较器重命名(例如改为NameComparator),保证同包下类名唯一。 - 修正构造方法赋值逻辑:把形参的值赋值给实例成员变量,正确写法为
this.eid = eid; this.ename = ename; - (可选优化)为集合、比较接口添加泛型声明,去掉不必要的强转逻辑,提升代码类型安全性。
修复后完整代码
package CollectionsPkg; import java.util.Comparator; import java.util.TreeSet; public class TreeSetDemo2 { public static void main(String[] args) { Employee e1=new Employee(20, "Catherine"); Employee e2=new Employee(36, "Helena"); Employee e3=new Employee(9, "Mathews"); Employee e4=new Employee(23, "Goblet"); Employee e5=new Employee(5, "Andrew"); TreeSet<Employee> t=new TreeSet<>(); t.add(e1); t.add(e2); t.add(e3); t.add(e4); t.add(e5); System.out.println("For Default sorting: "+t); TreeSet<Employee> t1=new TreeSet<>(new MyComparator1()); t1.add(e1); t1.add(e2); t1.add(e3); t1.add(e4); t1.add(e5); System.out.println("Customized Sorting based on Alphabetical order: "+t1); } } class Employee implements Comparable<Employee>{ int eid; String ename; Employee(int eid,String ename){ // 修正赋值方向 this.eid = eid; this.ename = ename; } public String toString() { return eid+" "+ename; } @Override public int compareTo(Employee e) { // 泛型优化后不需要强转 int eid1= this.eid; int eid2=e.eid; if(eid1<eid2) { return -1; } else if(eid1>eid2) { return 1; } else return 0; } } class MyComparator1 implements Comparator<Employee>{ // 泛型优化后不需要强转 public int compare(Employee e1,Employee e2) { String s1=e1.ename; String s2=e2.ename; return s1.compareTo(s2); } }
运行结果
For Default sorting: [5 Andrew, 9 Mathews, 20 Catherine, 23 Goblet, 36 Helena] Customized Sorting based on Alphabetical order: [5 Andrew, 20 Catherine, 23 Goblet, 36 Helena, 9 Mathews]
内容的提问来源于stack exchange,提问作者PranjalTech
相关产品推荐
相关产品推荐

