java中同类对象之间的compareTo()和compare()方法对比分析

首先我们都知道java中的比较都是同一类对象与对象之间的比较,就好像现实生活中比较人和人的年龄一样,你不会去把人的年龄和人的身高来比较,这显然是没有意义的。

java中同类对象之间的比较又分为两种,基本类型之间的比较和引用类型之间的比较。

java中“==”比较对象是否引用了同一个对象,或者比较基本类型变量值是否相等。Object类的equals()方法用来比较是否一个对象(内存地址比较),可以重写。

JDK中有些类重写了equals()方法,只要类型、内容都相同,就认为相等。很变态的Boolean类,仅存在两个实例。

具体可查看API。一般来说,一个类如果涉及到比较,应该重写equals()方法,因为内存地址比较没有意义。

关于上述两种比较方式可以查看 https://www.jb51.net/article/195717.htm,这里我就不做过多的解释了

以上两种所述的方式都是只能比较对象与对象相不相等,但是这显然是不够的,我们往往需要的是它们之间的大小比较,当然对于基本类型值大小之间的比较,我们常用的是“>”,“<”等方法,这里我做解释。

但关于对象与对象之间的大小比较,主要有类实现Comparable接口(重写compareTo()方法),或提供Comparator接口(重写compare()方法)。

compareTo()方法

重写compareTo()方法是实现Comparable接口的使用(自然排序)规则:如果当前对象this大于形参对象obj,则返回正整数,如果当前对象this小于形参对象obj,则返回负整数。如果当前对象this等于形参对象obj,则返回零。

public class Test {
 public static void main(String[] args) {
  Student stu1 = new Student("hubert",20);
  Student stu2 = new Student("jake",18);
  System.out.println(stu1.compareTo(stu2));//结果为1
 }
}

class Student implements Comparable<Student>{
 private String name;
 private int age;

 public Student(String name, int age) {
  this.name = name;
  this.age = age;
 }
 @Override
 public int compareTo(Student o) {
  return this.age<o.age?-1:this.age==o.age?0:1;
 }
}

compare()方法

重写compare()方法是提供Comparator接口的使用 (定制排序)。重写compare(Object o1,Object o2)方法,比较o1和o2的大小,如果方法返回正整数,则表示o1大于o2,如果返回0,表示二者相等,如果返回负整数,表示o1小于o2.

引入原因:当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作可以考虑使用Comparator的对象来实现排序。

import java.util.Comparator;

public class Test {
 public static void main(String[] args) {
  Student stu1 = new Student("hubert",20);
  Student stu2 = new Student("jake",18);
  int compare = new Comparator<Student>() {
   @Override
   public int compare(Student o1, Student o2) {
    return o1.getAge() < o2.getAge() ? -1 : o1.getAge() == o2.getAge() ? 0 : 1;
   }
  }.compare(stu1, stu2);
  System.out.println(compare);

 }
}

class Student{
 private String name;
 private int age;

 public Student(String name, int age) {
  this.name = name;
  this.age = age;
 } 

 public int getAge() {
  return age;
 }

}

Comparator接口有两个抽象方法,一个是compare,另一个是equals方法,而写这个匿名内部类时,可以不重写equals方法,但所有的类都继承Object,所以可以不实现equals方法

Comparable接口与Comparator接口的使用对比

Comparable接口的方式一旦指定,保证Comparable接口实现类的对象在任何位置都可以比较大小。

Comparator接口属于临时性的比较。

以上这篇java中同类对象之间的compareTo()和compare()方法对比分析就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

时间: 2020-09-15

java使用compareTo实现一个类的对象之间比较大小操作

首先定义一个对象,注意这个对象必须实现Comparable接口,并重写这个接口的compareTo方法 package cn.demo; public class Student implements Comparable{ private int number=0; //学号 private String name=""; //学生姓名 private String gender=""; //性别 public int getNumber(){ return nu

Java中替代equals,compareTo和toString的方法

我们都曾在POJO中重写过equals(),compareTo()和toString()方法.但是另有其他能做到职责分离的更好的方法并带来更简洁的代码.阅读这篇文章来一探究竟吧! 更简明的职责--摆脱equals.compareTo和toString方法 你曾经查看过java文档中的Object类吗?也许吧.每当你向上追溯继承树的时候都会止步于这个类.你会注意到,该类有几个方法是每一个类都必须继承的.而你最喜欢重写的方法可能就是toString(), .equals() and .hashCod

Java中比较运算符compareTo()、equals()与==的区别及应用总结

前言 比较运算符用于判断两个数据的大小,例如:大于.等于.不等于.比较的结果是一个布尔值( true 或 false ). Java 中常用的比较运算符如下表所示: 本文主要给大家介绍了关于Java比较运算符compareTo().equals()与==区别及应用的相关内容,下面话不多说了,来一起看看详细的介绍吧 1.== 和 equals的区别: ==主要是两个变量值的比较,返回值为true 或者是false.对于普通变量,如:int a=10; int  b= 10; a==b,返回为 tr

java源码解析之String类的compareTo(String otherString)方法

一. 前言 最近我发现了一个事情,那就是在面试笔试中,好多公司都喜欢在String字符串上出问题,涉及到方方面面的知识,包括其中的一些常用方法. String 类代表字符串.Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现. 字符串是常量:它们的值在创建之后不能更改.字符串缓冲区支持可变的字符串.因为 String 对象是不可变的,所以可以共享. 近日研究了一下String类的一些方法, 通过查看源码, 对一些常用的方法也有了更透彻的认识, 也让我更加理解了设

Java源码解析之object类

在源码的阅读过程中,可以了解别人实现某个功能的涉及思路,看看他们是怎么想,怎么做的.接下来,我们看看这篇Java源码解析之object的详细内容. Java基类Object java.lang.Object,Java所有类的父类,在你编写一个类的时候,若无指定父类(没有显式extends一个父类)编译器(一般编译器完成该步骤)会默认的添加Object为该类的父类(可以将该类反编译看其字节码,不过貌似Java7自带的反编译javap现在看不到了). 再说的详细点:假如类A,没有显式继承其他类,编译

Java源码解析之TypeVariable详解

TypeVariable,类型变量,描述类型,表示泛指任意或相关一类类型,也可以说狭义上的泛型(泛指某一类类型),一般用大写字母作为变量,比如K.V.E等. 源码 public interface TypeVariable<D extends GenericDeclaration> extends Type { //获得泛型的上限,若未明确声明上边界则默认为Object Type[] getBounds(); //获取声明该类型变量实体(即获得类.方法或构造器名) D getGenericDe

Java源码解析之GenericDeclaration详解

学习别人实现某个功能的设计思路,来提高自己的编程水平.话不多说,下面进入正题. GenericDeclaration 可以声明类型变量的实体的公共接口,也就是说,只有实现了该接口才能在对应的实体上声明(定义)类型变量,这些实体目前只有三个:Class(类).Construstor(构造器).Method(方法)(详见:Java源码解析之TypeVariable详解 源码 public interface GenericDeclaration { //获得声明列表上的类型变量数组 public T

String类下compareTo()与compare()方法比较

String类下compareTo()与compare()方法比较 这两个方法经常搞混淆,现对其进行总结以加深记忆. compareTo(Object o)方法是java.lang.Comparable<T>接口中的方法, 当需要对某个类的对象进行排序时,该类需要实现Comparable<T>接口的, 必须重写public int compareTo(T o)方法, 比如MapReduce中Map函数和Reduce函数处理的 <key,value>, 其中需要根据key

Java源码解析ThreadLocal及使用场景

ThreadLocal是在多线程环境下经常使用的一个类. 这个类并不是为了解决多线程间共享变量的问题.举个例子,在一个电商系统中,用一个Long型变量表示某个商品的库存量,多个线程需要访问库存量进行销售,并减去销售数量,以更新库存量.在这个场景中,是不能使用ThreadLocal类的. ThreadLocal适用的场景是,多个线程都需要使用一个变量,但这个变量的值不需要在各个线程间共享,各个线程都只使用自己的这个变量的值.这样的场景下,可以使用ThreadLocal.此外,我们使用ThreadL

Java源码解析HashMap简介

本文基于jdk1.8进行分析 HashMap是java开发中可以说必然会用到的一个集合.本文就HashMap的源码实现进行分析. 首先看一下源码中类的javadoc注释对HashMap的解释.如下图.HashMap是对Map接口的基于hash表的实现.这个实现提供了map的所有可选操作,并且允许null值(可以多个)和一个null的key(仅限一个).HashMap和HashTable十分相似,除了HashMap是非同步的且允许null元素.这个类不保证map里的顺序,更进一步,随着时间的推移,

Java源码解析阻塞队列ArrayBlockingQueue功能简介

本文基于jdk1.8进行分析. 阻塞队列是java开发时常用的一个数据结构.首先看一下阻塞队列的作用是什么.阻塞队列的作用,从源码中类的注释中来了解,是最清晰准确的. ArrayBlockingQueue是一个用数组实现的有界阻塞队列.提供FIFO的功能.队列头上的元素是在队列中呆了最长时间的元素,队列尾上的元素是在队列中呆了时间最短的元素.新元素会插入在队列尾部,从队列获取元素时会从队列头上获取. 这是一个传统的有界队列,在这个有界队列里,一个固定大小的数组用来保存生产者产生的元素和消费者获取

Java源码解析之可重入锁ReentrantLock

本文基于jdk1.8进行分析. ReentrantLock是一个可重入锁,在ConcurrentHashMap中使用了ReentrantLock. 首先看一下源码中对ReentrantLock的介绍.如下图.ReentrantLock是一个可重入的排他锁,它和synchronized的方法和代码有着相同的行为和语义,但有更多的功能.ReentrantLock是被最后一个成功lock锁并且还没有unlock的线程拥有着.如果锁没有被别的线程拥有,那么一个线程调用lock方法,就会成功获取锁并返回.

Java源码解析HashMap的keySet()方法

HashMap的keySet()方法比较简单,作用是获取HashMap中的key的集合.虽然这个方法十分简单,似乎没有什么可供分析的,但真正看了源码,发现自己还是有很多不懂的地方.下面是keySet的代码. public Set<K> keySet() { Set<K> ks = keySet; if (ks == null) { ks = new KeySet(); keySet = ks; } return ks; } 从代码中了解到,第一次调用keySet方法时,keySet