文章目录

  • Comparable
  • Comparator
  • Cloneable
    • 浅拷贝
    • 深拷贝

Comparable

当我们需要对一个自己写的类进行排序(Collections.sortArrays.sort)的时候,,就要使用到Comparable接口。

该接口中有一个compareTo方法,该方法其实就是一比较规则。

public interface Comparable<T> {public int compareTo(T o);
}

然后比较当前对象和参数对象的大小关系(按分数来算).

  • 如果当前对象应排在参数对象之前, 返回小于 0 的数字;
  • 如果当前对象应排在参数对象之后, 返回大于 0 的数字;
  • 如果当前对象和参数对象不分先后, 返回 0

所以如果自己的类需要进行排序的时候,就需要实现Comparable该接口,并重写compareTo方法,该法就可以通过指定字段进行排序,比如年龄。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;class Student implements Comparable<Student> {int id;String name;int age;public Student(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}// 谁调用的compareTo,谁就是this@Overridepublic int compareTo(Student o) {return this.age -o.age;}
}
public class TestDemo {public static void main(String[] args) {List<Student> students = new ArrayList<>();students.add(new Student(2,"张三",20));students.add(new Student(3,"李四",18));students.add(new Student(1,"王五",15));System.out.println(students);Collections.sort(students);System.out.println(students);}
}

运行结果

[Student{id=2, name='张三', age=20}, Student{id=3, name='李四', age=18}, Student{id=1, name='王五', age=15}]
[Student{id=1, name='王五', age=15}, Student{id=3, name='李四', age=18}, Student{id=2, name='张三', age=20}]

该接口对类的侵入性比较强,但是如果这个比较规则已经被很多人使用,你突然想换个比较规则,如果修改比较规则必然会造成损失,所以这个方方法对类的侵入性太强了,并不是特别好。

Comparator

刚刚我们说 Comparable 对类的侵入性太强了,但有另外一个接口它十分灵活。就是Comparator

代码示例:

我们写了两个类,分别实现了 Comparator 这个接口,一个是用年龄比较,一个是用姓名比较。我们叫做比较器.

import java.util.Comparator;public class AgeComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.age-o2.age;}
}
import java.util.Comparator;public class NameComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.name.compareTo(o2.name);}
}

再来看原来的代码,我们的Student并没有实现任何接口,也没有重写compareTo 方法。
只是实例化了刚刚上面两个比较器,在用sort排序时,传过去了两个参数,一个是要排序的集合,一个是我们写的比较器对象。

class Student{int id;String name;int age;public Student(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}
}
public class TestDemo {public static void main(String[] args) {List<Student> students = new ArrayList<>();students.add(new Student(3,"李四",18));students.add(new Student(1,"王五",15));students.add(new Student(2,"张三",20));System.out.println(students);//按姓名排序NameComparator nameComparator = new NameComparator();Collections.sort(students,nameComparator);System.out.println(students);// 按年龄排序AgeComparator ageComparator = new AgeComparator();Collections.sort(students,ageComparator);System.out.println(students);}
}

运行结果

[Student{id=3, name='李四', age=18}, Student{id=1, name='王五', age=15}, Student{id=2, name='张三', age=20}]
[Student{id=2, name='张三', age=20}, Student{id=3, name='李四', age=18}, Student{id=1, name='王五', age=15}]
[Student{id=1, name='王五', age=15}, Student{id=3, name='李四', age=18}, Student{id=2, name='张三', age=20}]

Comparator 接口,如果要进行比较只需要根据自己的需要写一个比较器就好了,并不像第一个接口那样直接写死了。

Cloneable

Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”. 但是要想合法调用 clone 方法, 必须要先实现Clonable接口

  • 实现Clonable接口
  • 记住要处理异常
  • 重写 Object 的 clone 方法
class Person implements Cloneable {String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class CloneableDemo {public static void main(String[] args) throws CloneNotSupportedException {Person std1 = new Person("张三",18);Person std2 = (Person) p1.clone();System.out.println(std1);System.out.println(std2);}
}

运行结果

Person{name='张三', age=18}
Person{name='张三', age=18}

此时的内存布局

如果一个类里的成员变量是另外一个类,使用clone对其进行拷贝

浅拷贝

class Test {int val;public Test(int val) {this.val = val;}@Overridepublic String toString() {return "Test{" +"val=" + val +'}';}
}
class Person implements Cloneable {String name;int age;Test t;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", t=" + t +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class CloneableDemo {public static void main(String[] args) throws CloneNotSupportedException {Person std1 = new Person("张三",18);std1.t = new Test(100);Person std2 = (Person) p1.clone();std2.t.val = 200;System.out.println(std1);System.out.println(std2);}
}

运行结果

Person{name='张三', age=18, t=Test{val=200}}
Person{name='张三', age=18, t=Test{val=200}}

当我们对拷贝后的对象也就是p2里的Test示例进行修改时,p1也发生了改变。此时就是一个典型的浅拷贝

此时的内存布局,这个拷贝就是将一个对象原样克隆了一份,它其时两个对象里的Test示例对象还是指向的同一个 对象

深拷贝

要想实现深拷贝,就得修改clone方法,再让其包含的Test类也要实现Cloneable接口重写clone接口,让Person对象在拷贝的同时把Test示例也给拷贝,这样就实现深拷贝。

class Test implements Cloneable {int val;public Test(int val) {this.val = val;}@Overridepublic String toString() {return "Test{" +"val=" + val +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
class Person implements Cloneable {String name;int age;Test t;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", t=" + t +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {Person person = (Person) super.clone();person.t = (Test) this.t.clone();return person;}
}
public class CloneableDemo {public static void main(String[] args) throws CloneNotSupportedException {Person p1 = new Person("张三",18);p1.t = new Test(100);Person p2 = (Person) p1.clone();p2.t.val = 200;System.out.println(p1);System.out.println(p2);}
}

运行结果

Person{name='张三', age=18, t=Test{val=100}}
Person{name='张三', age=18, t=Test{val=200}}

此时的内存布局


Comparable+Comparator+Cloneable接口相关推荐

  1. Comparable接口、Comparator接口、Cloneable接口

    Comparable接口与比较器Comparator接口 Comparable接口用来比较两个对象属性的大小,实现Comparable接口需要重写compareTo抽象方法,通过重写并调用compar ...

  2. Comparable Comparator的区别

    Comparable & Comparator接口都可以用来实现集合中元素的比较.排序,Comparator位于包java.util下, Comparable位于包java.lang下 Com ...

  3. java常用类库---比较器(Comparable,Comparator)

    一,本章目标 掌握Comparable比较接口的使用 了解比较器的基本排序原理 掌握Comparator比较接口的使用 二,具体内容 Comparable接口: 之前在Arrays中存在sort方法, ...

  4. Java中的Cloneable接口

    1.Cloneable接口的作用 Cloneable是标记接口(其方法体为空),它用来表示一个类拥有某些希望具有的特征.实现Cloneable接口的类被标记为可克隆的,而且其对象可以使用Object类 ...

  5. java语言之Cloneable接口

    在我们学习过程中,会发现java很多非常重要的接口,比如Cloneable,Serializable,Comparable等等之类的,今天我就总结一下Cloneable接口. 我学习到现在觉得最好的学 ...

  6. java cloneable 接口_Cloneable 接口 记号接口(标记接口)

    Cloneable 接口指示了一个类提供了一个安全的clone方法. 首先了解Object.clone()方法: clone是Object超类的一个protected方法,用户代码不能直接调用这个方法 ...

  7. Comparable和Cloneable

    Comparable: 该接口中的只有一个compareTo(T o)方法: public interface Comparable<T> {public int compareTo(T ...

  8. comparable, comparator

    阅读目录 一.Comparable简介 二.Comparator简介 三.Comparable和Comparator区别比较 回到顶部 一.Comparable简介 Comparable是排序接口.若 ...

  9. Cloneable接口和循环冗余校验算法

    1 Cloneable 接口 实现该接口的类可以调用clone()方法合法地对该类实例进行按字段复制.按照惯例,实现此接口的类应该使用公共方法重写 Object.clone(它是受保护的) 2 循环冗 ...

最新文章

  1. 激光雷达激烈竞争市场
  2. Xilinx FPGA部分重配置操作流程
  3. Asp.net Ajax框架教程
  4. python读取csv文件的方法-python读写csv文件的方法
  5. element ui点击按钮弹出款_前端猿应该知道的十大最流行的前端UI框架
  6. 【git】之使用shell脚本提交代码
  7. Go web framework
  8. 第五十一期:互联网不如国企,去BAT的程序员都是diao丝?
  9. 初二物理模型有哪些_暑假新初二、新初三的数学该怎么学,教辅怎么买,题该怎么刷?看这里~...
  10. 苏宁双11战报:0点~1点 线上订单同比增72%
  11. bankeralgorithm.jar中没有主清单属性_怀旧服:迅击指环和其拉之怒属性一致,为何狂暴战用迅击更好...
  12. python 迭代多个对象
  13. Pycharm导入python项目
  14. [GitHub][2014-05-13 06:00:39]JavaDsp
  15. [转]摄影入门导购-基于预算的器材解决方案
  16. 【今年年会,你中奖了吗?】在线抽奖活动中如何实现中奖概率的自适应调整...
  17. crossover程序错误_如何使用Crossover在Linux上安装Windows应用程序
  18. TalkingData的移动大数据探索:联合Kochava发布移动广告监测国际版
  19. 新概念,数字游民面临的一些挑战和应对举措
  20. 配置fedora 33

热门文章

  1. Synergy 使用
  2. 30个Kafka常见错误小集合
  3. 【转】Kbps、KB、Mbps单位换算
  4. 2020年6月7日日记
  5. 双机热备、双机互备、双机双工之间的区别
  6. 电磁兼容工程(Electromagnetic compatibility engineering Herry Ott )读书笔记-- 章14 抗射频和瞬态信号干扰能力
  7. 梦幻手游服务器维护摆摊公示时间,梦幻西游手游摆摊交易优化 11号维护安卓多区合服...
  8. TokenGazer评级丨Monero:XMR缓慢发行损害矿工利益,去中心化治理带来社区分裂风险...
  9. 计算语言学(CL)与自然语言处理(NLP)
  10. jarvis OJ web babyphp