数据结构——Java对象的比较

目录

一、基本类型的比较

二、对象的比较

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);    //false
    double a1=1.1;
    double b1=1.2;
    System.out.println(a1<b1);    //true

    char c='a';
    char d='b';
    System.out.println(c>d);    //flase
    
    boolean 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;
	}
	@Override
	public boolean equals(Object o){
		//与自身相比较,如果指向同一个对象,返回true
		if(this==o){
			return true;
		}
		if(o==null||!(o instanceof dog)){
			//如果传入的为null,或者o不是dog的子类,返回false
			return 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;
	}
	@Override
	public 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>{
	@Override
	public 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>{
	@Overrider
	public int compare(Integer o1,Integer o2){
		return o1-o2;
	}
}

(2).使用比较器创建大根堆

class cmp2 implements Comparator<Integer>{
	@Overrider
	public 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;
	}
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值