Java数据布局_一篇文章搞定java对象的比力_7

[复制链接]
发表于 2025-10-26 19:38:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
1. PriorityQueue中插入对象

上篇文章研究了优先级队列,优先级队列在插入元素中,要求插入的元素不能是null大概元素之间必须要可以或许举行比力,为了简朴起见,上篇文章只是插入了Integer范例,那优先级队列中是否能插入自界说范例的对象呢?
有如下代码:
  1. class Card {
  2.     private int rank; //数值
  3.     private String suit; //花色
  4.     public Card(int rank, String suit) {
  5.         this.rank = rank;
  6.         this.suit = suit;
  7.     }
  8. }
  9. public class Test {
  10.     public static void TestForPriority() {
  11.         PriorityQueue<Card> p = new PriorityQueue<>();
  12.         p.offer(new Card(1, "♥"));
  13.         p.offer(new Card(2, "♥"));
  14.     }
  15.     public static void main(String[] args) {
  16.         TestForPriority();
  17.     }
  18. }
复制代码
运行效果为:

缘故因由在上篇文中也有所提及,优先级队列底层使用堆,而向堆中插入元素中,为了满意堆的性子(offer方法中会检测是否有比力器,如果没有比力器会强转为Compareable),必须要举行元素的比力,而此时自界说范例Card是没有办法直接举行比力的,以是会抛出上面的非常。
2. 元素的比力

2.1 根本范例的比力

Java中,根本范例的对象可以直接比力巨细
  1. public class TestCompare {
  2.     public static void main(String[] args) {
  3.         int a = 10;
  4.         int b = 20;
  5.         System.out.println(a > b);
  6.         System.out.println(a < b);
  7.         System.out.println(a == b);
  8.         char c1 = 'A';
  9.         char c2 = 'B';
  10.         System.out.println(c1 > c2);
  11.         System.out.println(c1 < c2);
  12.         System.out.println(c1 == c2);
  13.         boolean b1 = true;
  14.         boolean b2 = false;
  15.         System.out.println(b1 == b2);
  16.         System.out.println(b1 != b2);
  17.     }
  18. }
复制代码
2.2 对象比力的题目

代码如下

如果在main方法中
有System.out.println(c1 > c2),会编译报错
有System.out.println(c1 == c2) 编译乐成 --> 打印false 由于c1和c2指向不是同一个对象
有System.out.println(c1 < c2) 会编译报错
有System.out.println(c1 == c3) 编译乐成 --> 打印true 由于c1 和 c3指向的是同一个对象
从上面的编译效果可以看出,Java中引用范例的变量不能直接按照 > 大概 < 举行比力 那 == 为什么可以呢?
对于自界说范例,都默认会继续自Object类,而Object类中提供了equals方法,而 == 默认情况下使用的是equals方法,但是该方法的默认比力规则是:没有比力引用变量引用对象的内容,而是直接比力引用变量的所在,但有些情况下这种比力并不符合题意。
下图为Object中equal的实现,可以看到:直接比力的是两个引用变量的所在

3. 对象的比力

有些情况下,必要比力的是对象中的内容,好比:向优先级队列中插入某个对象时,必要对按照对象中内容来调解 堆,那该怎样处置处罚呢?
3.1 覆写基类的equals方法

如图:在自界说类中重写equals方法
注意: 一样平常覆写 equals 的套路就是上面演示的
1. 如果指向同一个对象,返回 true
2. 如果传入的为 null,返回 false
3. 如果传入的对象范例不是 Card,返回 false
4. 按照类的实现目的完成比力,比方这里只要花色和数值一样,就以为是类似的牌
5. 注意下调用其他引用范例的比力也必要 equals,比方这里的 suit 的比力
重写equals方法固然可以举行比力,但缺点是:equal方法的返回值是boolean范例,只能按照相称的比力,不能按照大于,小于的方式举行比力。
3.2 基于Comparable接口类的比力

Comparable是JDK提供的泛型的比力接口类,源码实现为:
public interface Comparable<E> {
        //返回值:
        // < 0:体现this指向的对象小于 o 指向的对象
        // > 0:体现this指向的对象大于 o 指向的对象
        // == 0: 体现this指向的对象即是 o 指向的对象
        int compareTo(E o);
}
对于用户自界说范例,如果要按照自己的方式举行比力时: 在界说类的时间,实现Comparable接口,然后在类中重写compareTo方法即可。
如下图:根据数值举行比力,不管花色,这里以为null是最小的

测试符合预期:

Comparable是java.lang中的接口类,可以直接使用。
3.3 基于比力器比力

具体实现步调如下:
1. 用户自界说比力器类,实现Comparator接口
public interface Comparator<T> {
        // 返回值: // < 0: 体现 o1 指向的对象小于 o2 指向的对象
        // == 0: 体现 o1 指向的对象即是 o2 指向的对象
        // > 0: 体现 o1 指向的对象即是 o2 指向的对象
        int compare(T o1, T o2);
}
注意区分Comparable  和 Comparator。
2.覆写Comparator中的compare方法

测试符合预期:

注意:Comparator是java.util包中的泛型接口类, 使用时必须导入对应的包。
3.4 三种方式的对比


增补表明第二和第三种比力方式:
2. Comparable.comparaTo:

比方代码:
  1. import java.util.ArrayList;
  2. import java.util.Collections;
  3. import java.util.List;
  4. class Employee implements Comparable<Employee> {
  5.     private String name;
  6.     private int age;
  7.     public Employee(String name, int age) {
  8.         this.name = name;
  9.         this.age = age;
  10.     }
  11.     @Override
  12.     public int compareTo(Employee other) {
  13.         return Integer.compare(this.age, other.age);
  14.     }
  15.     public int getAge() {
  16.         return age;
  17.     }
  18.     @Override
  19.     public String toString() {
  20.         return "Employee{name='" + name + "', age=" + age + "}";
  21.     }
  22. }
  23. public class Main {
  24.     public static void main(String[] args) {
  25.         List<Employee> employees = new ArrayList<>();
  26.         employees.add(new Employee("Alice", 25));
  27.         employees.add(new Employee("Bob", 20));
  28.         employees.add(new Employee("Charlie", 30));
  29.         // 对员工列表进行排序
  30.         Collections.sort(employees);
  31.         for (Employee employee : employees) {
  32.             System.out.println(employee);
  33.         }
  34.     }
  35. }
复制代码

2. Comparator.compare
  1. import java.util.ArrayList;
  2. import java.util.Collections;
  3. import java.util.List;
  4. public class Main {
  5.     public static void main(String[] args) {
  6.         List<Student> students = new ArrayList<>();
  7.         students.add(new Student("Alice", 20));
  8.         students.add(new Student("Bob", 18));
  9.         students.add(new Student("Charlie", 22));
  10.         // 创建比较器对象
  11.         AgeComparator ageComparator = new AgeComparator();
  12.         // 在排序算法中显式指定比较器
  13.         Collections.sort(students, ageComparator);
  14.         for (Student student : students) {
  15.             System.out.println(student.getName() + " - " + student.getAge());
  16.         }
  17.     }
  18. }
复制代码


完!
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表