马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
1. PriorityQueue中插入对象
上篇文章研究了优先级队列,优先级队列在插入元素中,要求插入的元素不能是null大概元素之间必须要可以或许举行比力,为了简朴起见,上篇文章只是插入了Integer范例,那优先级队列中是否能插入自界说范例的对象呢?
有如下代码:- class Card {
- private int rank; //数值
- private String suit; //花色
- public Card(int rank, String suit) {
- this.rank = rank;
- this.suit = suit;
- }
- }
- public class Test {
- public static void TestForPriority() {
- PriorityQueue<Card> p = new PriorityQueue<>();
- p.offer(new Card(1, "♥"));
- p.offer(new Card(2, "♥"));
- }
- public static void main(String[] args) {
- TestForPriority();
- }
- }
复制代码 运行效果为:
缘故因由在上篇文中也有所提及,优先级队列底层使用堆,而向堆中插入元素中,为了满意堆的性子(offer方法中会检测是否有比力器,如果没有比力器会强转为Compareable),必须要举行元素的比力,而此时自界说范例Card是没有办法直接举行比力的,以是会抛出上面的非常。
2. 元素的比力
2.1 根本范例的比力
Java中,根本范例的对象可以直接比力巨细- public class TestCompare {
- public static void main(String[] args) {
- int a = 10;
- int b = 20;
- System.out.println(a > b);
- System.out.println(a < b);
- System.out.println(a == b);
-
- char c1 = 'A';
- char c2 = 'B';
- System.out.println(c1 > c2);
- System.out.println(c1 < c2);
- System.out.println(c1 == c2);
-
- boolean b1 = true;
- boolean b2 = false;
- System.out.println(b1 == b2);
- System.out.println(b1 != b2);
- }
- }
复制代码 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:
比方代码:- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- class Employee implements Comparable<Employee> {
- private String name;
- private int age;
- public Employee(String name, int age) {
- this.name = name;
- this.age = age;
- }
- @Override
- public int compareTo(Employee other) {
- return Integer.compare(this.age, other.age);
- }
- public int getAge() {
- return age;
- }
- @Override
- public String toString() {
- return "Employee{name='" + name + "', age=" + age + "}";
- }
- }
- public class Main {
- public static void main(String[] args) {
- List<Employee> employees = new ArrayList<>();
- employees.add(new Employee("Alice", 25));
- employees.add(new Employee("Bob", 20));
- employees.add(new Employee("Charlie", 30));
- // 对员工列表进行排序
- Collections.sort(employees);
- for (Employee employee : employees) {
- System.out.println(employee);
- }
- }
- }
复制代码
2. Comparator.compare
 - import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- public class Main {
- public static void main(String[] args) {
- List<Student> students = new ArrayList<>();
- students.add(new Student("Alice", 20));
- students.add(new Student("Bob", 18));
- students.add(new Student("Charlie", 22));
- // 创建比较器对象
- AgeComparator ageComparator = new AgeComparator();
- // 在排序算法中显式指定比较器
- Collections.sort(students, ageComparator);
- for (Student student : students) {
- System.out.println(student.getName() + " - " + student.getAge());
- }
- }
- }
复制代码
完!
|