目录
一、基本类型的比较
二、对象的比较
1、定义
2、方法
(1).覆写基类的equals
(2).基于Comparable接口类的比较
(3).基于比较器的比较
3、对比
三、集合框架中的PriorityQueue的比较方式
四、应用——解决Topk问题
1、PriorityQueue创建大根堆和小根堆
(1).使用比较器创建小根堆
(2).使用比较器创建大根堆
2、代码
一、基本类型的比较
Java中的基本类型的对象可以直接比较大小
public static void main(String[] args){int a=1;int b=2;System.out.println(a>b); //falsedouble a1=1.1;double b1=1.2;System.out.println(a1<b1); //truechar c='a';char d='b';System.out.println(c>d); //flaseboolean e=false;boolean f=true;System.out.println(e==f); //false
}
二、对象的比较
1、定义
Java中引用类型的变量不能直接按照“>”或“<”方式进行比较。但是可以用“==”进行比较,因为对于用户实现自定义类型,都是默认继承自Object类,Object类中提供了equal方法,而“==”默认情况下调用的就是equal方法。该方法的比较规则是没有比较引用变量引用对象的内容,而是直接比较引用变量的地址,因此很多时候不适用。
public boolean equals(Object obj){return (this==obj);//直接比较两个引用变量的地址
}
2、方法
(1).覆写基类的equals
public class dog{public int age;public String name;public dog(int age,String name){this.age=age;this.name=name;}@Overridepublic boolean equals(Object o){//与自身相比较,如果指向同一个对象,返回trueif(this==o){return true;}if(o==null||!(o instanceof dog)){//如果传入的为null,或者o不是dog的子类,返回falsereturn false;}dog d=(dog)o;//只要类中的两个对象都相等,就认为两个类相等return age==d.age&&name.equals(d.name);}
}
注:覆写基类equal的方式虽然可以比较,但缺陷是equal只能按照相等进行比较,不能按照大于或小于的方式进行比较 。
(2).基于Comparable接口类的比较
Comparable是JDK提供的泛型的比较接口类。
public interface Comparable<E>{int compareTo(E o);//<0:表示this指向的对象小于o指向的对象//==0:表示this指向的对象等于o指向的对象//>0:表示this指向的对象大于o指向的对象
}
注:Comparable是java.lang中的接口类,可以直接使用,不需要导包
对于用户自定义类型,如果想要按照大小与方式进行比较时。在定义类时,实现Comparable接口即可,然后在类中重写compareTo方法。
public class dog implements Comparable<dog>{public int age;public String name;public dog(int age,String name){this.age=age;this.name=name;}@Overridepublic int compareTo(dog d){if(o==null){return 1;}return age-d.age;}public static void main(String[] args){dog d1=new dog(10,"二哈");dog d2=new dog(12,"二哈");dog d3=new dog(10,"二哈")System.out.println(d1.compareTo(d3)); //==0,表示相等System.out.println(d1.compareTo(d2)); //<0,表示d1比较小System.out.println(d2.compareTo(d1)); //>0,表示d2比较大}
}
(3).基于比较器的比较
用户自定义比较器类,实现Comparator接口
public interface Comparator<T>{int compare(T o1,T o2);//<0:表示o1指向的对象小于o2指向的对象//==0:表示o1指向的对象等于o2指向的对象//>0:表示o1指向的对象大于o2指向的对象
}
注:Comparator是java.util包中的泛型接口类,使用前需要导包
覆写Comparator中的compare方法
import java.util.Comparator;
class dog{public int age;public String name;public dog(int age,String name){this.age=age;this.name=name;}
}
class dogComparator implements Comparator<dog>{@Overridepublic int compare(dog d1,dog d2){if(d1==d2){return 0;}if(o1==null){return -1;}if(o2==null){return 1;}return d1.age-d2.age;}public static void main(String[] args){dog d1=new dog(10,"二哈");dog d2=new dog(12,"二哈");dog d3=new dog(10,"二哈");//定义比较器对象dogComparator c=new dogComparator();//使用比较器对象进行比较System.out.println(c.compare(d1,d3)); //==0,表示牌相等System.out.println(c.compare(d1,d2)); //<0,表示d1比较小System.out.println(c.compare(d2,d1)); //>0,表示d2比较大}
}
3、对比
Object.equals | 因为所有类都是继承自Object的,所以直接覆写即可,不过只能比较相等与否 |
Comparable.compareTo | 需要手动实现接口,侵入性较强,但一旦实现,每次用该类都有顺序,属于内部顺序 |
Comparator.compare | 需要实现一个比较器对象,对待比较类的侵入性弱,但对于算法代码实现侵入性强 |
三、集合框架中的PriorityQueue的比较方式
集合框架中的PriorityQueue底层使用堆结构,因此其内部的元素必须能够比大小,PriorityQueue采用了Comparable和Comparator两种方式
- Comparable是默认的内部比较方式,如果用户插入自定义类型对象时,该类对象必须要实现Comparable接口,并覆写compareTo方法
- 用户使用比较器对象时,如果用户插入自定义类型对象时,必须要提供一个比较器类,让该类实现Comparator接口并覆写compare方法
四、应用——解决Topk问题
1、PriorityQueue创建大根堆和小根堆
(1).使用比较器创建小根堆
class cmp1 implements Comparator<Integer>{@Overriderpublic int compare(Integer o1,Integer o2){return o1-o2;}
}
(2).使用比较器创建大根堆
class cmp2 implements Comparator<Integer>{@Overriderpublic int compare(Integer o1,Integer o2){return o2-o1;}
}
2、代码
public class test{public static int[] func(int[] array,int k){if(k<=0){return new int[k];}cmp2 c=new cmp2();PriorityQueue<Integer> maxHeap=new PriorityQueue<>(c);for(int i=0;i<k;i++){maxHeap.offer(array[i]);}for(int i=k;i<array.length;i++){int top=maxHeap.peek();if(array[i]<top){maxHeap.poll();maxHeap.offer(array[i]);}}int[] ret=new int[k];for(int i=0;i<k;i++){int val=maxHeap.poll();ret[i]=val;}return ret;}
}