Deep Dive: PriorityQueue需要如何比较两个item(自己定义的/原本就有的)

Summary

  • 如果你本身就有自然序列/comparable,那么就写一个comparator(类 或者换comparator)

    • 可以共享定义

    • 可以一个定义有多个comparator

  • 你创建一个新的,就自己写comparable(说白了comparable是他自己有的)

Method 1. Object 本身实现Comparable Interface: Override compareTo(E e) Method in Comparable interface

https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html

Method 2: 实现Comparator Interface Override compare(E e1, E e2) Method in Comparator interface

https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html

接口名
方法名

interface Comparable<E> {

int compareTo(E ele);

}

int compareTo(T o)

interface Comparator<E> {

int compare(E o1, E o2);

}

int compare(T o1, T o2);

Method 1. Implementation Comparable

Class 1: 原本就存在于Java中的的Object实现Comparable Interface

// Some code

interface Comparable<E> {
    int compareTo(E ele);
}

class Integer implements Comparable<Integer> {
    private int value;
    public Integer(int value){
        this.value = value;
    }
    @Override
    public int compareTo(Integer another) {
        if (this.value == another.value) {
            return 0;
        }
        return this.value < another.value? -1: 1;
    }
}


// 例子
public static void main(String[] args){
    Integer one = new Integer(1);
    Integer two = new Integer(2);
    System.out.println(one.compareTo(two));
}

The return value of compareTo(another) method determines the order of this and another: 0: this and another are of the same priority -1(<0): this has higher priority than another 1 (>0): this has less priority than another

CompareTo 的Return Value(int) 代表什么含义(this.compareTo(other)) - 0: this 和other的优先级相同(因为大小一样) -1: this 小于other,因为this小,所以this优先 1: this大于other,因为other小,所以other优先

Class 2: 我们自己定义的Class Implement Comparable

Method 2.实现Comparator Interface Override compare(E e1, E e2) Method in Comparator interface

Provide an extra Comparator object to compare the elements

This is another interface Comparator, and it is used to compare two elements with the same type E.

如何把这个Comaprator传进PriorityQueue?

一些问题

Question 1 有咩有可能一个类已经实现了Comarable, 那这个时候我能写这个Class的Comaprator吗?

可以: 语义

你说1 比2小,我不同意,在我这1就比2大

Question 2 如何让PriorityQueue 不按照Comparable的compare To来比较,而是用我们定义的Comparator的compare来比较呢?

Question 3: 那这样,叫minHeap还合适吗?那怎么创建maxHeap

  • 用新建comparator

  • Collections.reverseOrder()?

Method 1:可以自己建立一个Comparator 让比较大的元素优先级高,传进PriortyQueue

Method 2:用Utility Method

  • 第二类可以用Collections.reverseOrder()

  • 本质: reverseOrder()这个方法本质上返回了一个Comparator(是一个instance),所以其实把Collections.reverseOrder()传进PriorityQueue相当于传进一个Comparator

  • 如果这个Item自己也实现了Comparable, 你同时也传进来Comparator的话,PriorityQueue会按照Comparator来比较。

    • If E already implements Comparable<E>, but you still provide a Comparator, PriorityQueue will choose the order specified in Comparator.

Question 4: 怎么有的PriorityQueue Constructor建立的时候要传数字(16),有的可以 传reverseOrder(),到底有多少种Constructor

  • 注意the inital capacity has to be >0;

  • most frequently used constructors of PriorityQueue

Requirement
Constructors

class Cell must implement Comparable<Cell>

new PriorityQueue<Cell>() (default capacity 11)

class Cell must implement Comparable<Cell>

new PriorityQueue<Cell>(16)

class MyComparator implements Comparator<Cell>

new PriorityQueue<Cell>(16, new MyComparator())

class MyComparator implements Comparator<Cell>

PriorityQueue<Cell>(new MyComparator())

  • if k < = 0, IllegalArgumentExpection will be thrown in the constructor. (k之前的16&11)

Question 5: 我记得有个方法就是把一个Collection变成一个Heap的方法叫做Heapify并且是O(n) 的,但是为啥在java doc里找不到

  • 注意,只能是传进去是collections,且必须要是自然序列

  • 所以不能给collection+ compartor且用heapify

  • 范型?将来可以放入任意类型?extend E

Question 6: 还是看不懂?

  • 不是new interface,而是创建类,且创建类interface。。。

  • Static nested class VS non-static class

    • belong to class, or belong to instance

  • Nest Class VS Inner Class

    • static nested class

      • a nested class associated with the outside class

      • can access class variables and method

    • inner class

      • a nested class associated with an instance of the class

      • can access instance variables and methods

    • anonymous class: nested class with no name

      • often replaceable by lambda expressions in Java 8

Question 6b: 五种version出现

  • Nested class vs inner class(无需知道。。。)

  • 直接在外面写

  • 不写?

  • 写inner class

  • lambda expression

Basic Version 1: 本来应该这样:亚古兽

Basic Version 1.5: 不想完整写一个Class: Static Nest Class

进化Version 2: 你别那么麻烦,如果你只是用一给,用这一次就是为了给我PriortyQueue里面传进来一个,那么没有必要定一个class,可以定一个没有名字,匿名内部类。重点在于告诉我们里面那个comapre方法长什么样子就可以了

new了一个匿名类(没有名字的)Comparator这个interface的实现类,里面的方法我给你了如下

进化 Version 3: Lambda Expressions

进化 Version 4

Last updated