如何使用Comparator实现两个Heap构造器以满足多规则汽车排序需求
先修正现有代码笔误
你当前Heap类里的比较器属性类型写错了,把Constructor修正为Comparator:
// 修正后的属性定义 private ArrayList<E> tree; private Comparator<? super E> cmp;
另外注意Car类的CompareTo方法需要改两个点:
- 方法名首字母小写为
compareTo,才是正确实现Comparable<Car>接口的方法 - 第三行判断条件的
make.compareTo(c.model)是笔误,修正为model.compareTo(c.model)
修正后的Car类compareTo方法:
@Override public int compareTo(Car c) { if (year != c.year) return year - c.year; if(make.compareTo(c.make) != 0) return make.compareTo(c.make); if(model.compareTo(c.model) != 0) return model.compareTo(c.model); return type.compareTo(c.type); }
同时Heap类的泛型定义需要约束E实现Comparable接口,完整类头定义为:
public class Heap<E extends Comparable<? super E>> { // 你的属性、方法定义放在这里 }
两个堆构造器实现
// 无参构造器:使用元素自然排序(即E的compareTo方法)作为比较规则 public Heap () { this.tree = new ArrayList<>(); // 自然排序比较器,默认调用元素的compareTo方法 this.cmp = Comparator.naturalOrder(); } // 带参构造器:使用外部传入的自定义比较器作为排序规则 public Heap(Comparator<? super E> fn) { this.tree = new ArrayList<>(); this.cmp = fn; }
后续堆的上浮、下沉调整逻辑里,所有比较两个元素a、b大小的地方,统一用cmp.compare(a, b)的返回值判断即可:返回负数说明a排在b前面,返回0说明相等,返回正数说明b排在a前面。
对应不同排序编码的Comparator构造示例
你可以根据传入的数字编码,生成对应的Comparator实例再传入Heap构造器即可,示例如下:
public static Comparator<Car> getComparatorByCode(int code) { return switch (code) { // -2: -make -> -model -> -type -> -year 全降序 case -2 -> Comparator.comparing(Car::getMake).reversed() .thenComparing(Car::getModel).reversed() .thenComparing(Car::getType).reversed() .thenComparingInt(Car::getYear).reversed(); // -1: -year -> -make -> -model -> -type 全降序,刚好是自然排序的逆序 case -1 -> Comparator.reverseOrder(); // 0: -type -> +year -> +make -> +model case 0 -> Comparator.comparing(Car::getType).reversed() .thenComparingInt(Car::getYear) .thenComparing(Car::getMake) .thenComparing(Car::getModel); // 1: +year -> +make -> +model -> +type 刚好是自然排序 case 1 -> Comparator.naturalOrder(); // 2: +make -> +model -> +type -> +year 全升序 case 2 -> Comparator.comparing(Car::getMake) .thenComparing(Car::getModel) .thenComparing(Car::getType) .thenComparingInt(Car::getYear); default -> throw new IllegalArgumentException("无效的排序编码"); }; }
main方法里调用时直接传对应的Comparator即可:
int sortCode = 1; // 从入参获取的排序编码 Heap<Car> heap = new Heap<>(getComparatorByCode(sortCode));
内容的提问来源于stack exchange,提问作者Nateclsu
相关产品推荐
相关产品推荐

