当前位置:网站首页>Analysis of the use of comparable, comparator and clonable interfaces
Analysis of the use of comparable, comparator and clonable interfaces
2022-07-02 08:23:00 【Ischanged】
Preface
java There are many interfaces in , Today, I will briefly introduce the three interfaces we usually use and their usage . Interfaces can be passed by classes emplements Keyword implementation , A class implements an interface , You have some functions of this interface , You can complete some operations .
Comparable Interface
Sort basic data types , Such as int ,long etc. , We can use Arrays.sort() And Collections.sort(), And this sort defaults to ascending sort, which cannot be changed , Such as the following sorting and shaping array :
public static void main(String[] args) {
int[] array = {
19,3,2,18,7,4};
System.out.println(Arrays.toString(array));
Arrays.sort(array);
System.out.println(Arrays.toString(array));
}
Sometimes we need to arrange custom data types , No matter whether we want to arrange in ascending or descending order, how to operate ????
In the following code , I defined a student class , If we also use Arrays.sort() Method to sort student objects will make mistakes , This is because we did not specify a comparison rule when comparing objects , When comparing students, is it sorted by name , Or age , Or scores , The compiler will report the following error if it doesn't know :
class Student {
private String name;
private int age;
private double score;
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
public class TestDemo {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("gb",28,99.9);
students[1] = new Student("bit",18,19.9);
students[2] = new Student("ang",98,69.9);
System.out.println(" Before ordering :"+Arrays.toString(students));
Arrays.sort(students);
System.out.println(" After ordering :"+Arrays.toString(students));
}
Then draw a red line Comparable What is it? ? In fact, it is an interface , There is a comparison function compare, All we have to do is student Implement this interface , You have the ability to compare , Then rewrite the comparison rules , Are you going to sort by name , Or scores , Just sort by age .
class Student implements Comparable<Student> {
//<Student> Is generic knowledge , After that, I will explain ,Student Indicates what type of data we want to compare
private String name;
private int age;
private double score;
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
// Compare the rules
@Override
public int compareTo(Student o) {
return (int) (this.score - o.score);// Ascending order of fractions
//return (int) (o.score - this.score);// The fractions are in descending order
//return this.name.compareTo(o.name);// Compare by name
//return o.age-this.age;// In descending order of age
//=============================================
// Decomposition of the above code
/*if(this.age > o.age) { return 1; }else if(this.age == o.age) { return 0; }else { return -1; }*//*
}
}*/
}
}
How to customize ascending and descending order ??? What's the rule , First, let's take a look Arrays.sort Part of the source code of this function .
for (int i=low; i<high; i++)
for (int j=i; j>low &&
((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
From the source code, we can roughly know , For the array elements to be sorted , Is called when the previous element is compared with the next element compareTo Method , and compareTo The method is our rewritten comparison rule , In the comparison rule, we will return greater than 0, be equal to 0, Less than 0 The number of , If the return is greater than 0 The number of , Then exchange the positions of the two elements And then from the top compareTo The method and source code are known ,o The object pointed to is the element after the two elements to be compared ,this The element pointed to is the first of the two elements to be compared , When comparing, if it is written as (this.score - o.score) That is to say, the previous element is greater than the latter element and returns greater than 0 The number of , In exchange for , This is the ascending order , The opposite is descending .
Then let's think again Comparable What's wrong with the interface ?? From the code, we can find that it is more intrusive to classes , That is to say, if the comparison method is changed every time , Then you need to modify the internal limitations of the class , so much trouble , Then there are better ones for comparison , More convenient comparison interface ? That's what we'll do next , I'm going to talk about the interface .
Comparator Interface
Comparator Interface is actually right Comparable Upgrade and improve , With it, we can make it more convenient to compare some custom data , quick . For example, for the student class instance customized above , We can according to age , fraction , Names achieve the sort we want . As long as we realize various The comparator , When sorting, send a comparator to Arrays.sort() that will do , In this way, the invasion of classes is relatively weak , There is no need to change the interior of the class frequently , The comparator is actually a comparison rule , We implement a class implementation Comparator After the interface, rewrite the abstract methods in the interface .
class Student {
private String name;
private int age;
private double score;
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
// The comparator
class AgeComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()-o2.getAge();
}
}
class NameComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
}
class ScoreComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return (int)(o1.getScore()-o2.getScore());
}
}
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("gb",28,99.9);
students[1] = new Student("bit",18,19.9);
students[2] = new Student("ang",98,69.9);
System.out.println(" Before ordering :"+Arrays.toString(students));
AgeComparator ageComparator = new AgeComparator();
NameComparator nameComparator = new NameComparator();
ScoreComparator scoreComparator = new ScoreComparator();
Arrays.sort(students,scoreComparator);
System.out.println(" After ordering :"+Arrays.toString(students));
}
The above is also used when comparing names compareTo() Method , The name is the string source code. The bottom layer is more abstract , Generally summarize the vernacular ,String Is string , Its comparison uses compareTo Method , First compare the lengths of the two strings , When the length is different, the length difference of the string is returned , In the same length , It starts from the first and then compares , If different characters are encountered , Immediately return the two characters ASCII The value difference . The return value is int type .
Comparable,Comparator A simple comparison between the two :
Comparable It's sort interface ; If a class implements Comparable Interface , Means “ This class supports sorting ”. and Comparator It's a comparator ; If we need to control the order of a class , You can build a “ This kind of comparator ” To sort . The former should be relatively fixed , It is also relatively invasive to classes , It is bound to a concrete class , The latter is more flexible , The invasion of classes is also relatively weak , It can be used for various classes that need comparison function .
Clonable Interface and deep copy
Object There is a clone Method , Call this method to create an object “ Copy ”. But if you want to call legally clone Method , It has to be done first Clonable Interface , Otherwise, it will throw CloneNotSupportedException abnormal .
class Person implements Cloneable{
public String name;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
public Person(String name) {
this.name = name;
}
//Object Cloning method of class . All the classes Default inheritance and Object class
@Override
protected Object clone() throws CloneNotSupportedException {
//return super.clone();
return super.clone();
}
}
public class TestDemo1 {
public static void main(String[] args) throws CloneNotSupportedException {
Person person=new Person("lmm");
System.out.println(person);
Person person2 = (Person)person.clone();// Note the cast
System.out.println(person2);
}
}
The implementation of this interface is not finished , Also rewrite the methods in this interface clone(), Because from the source code , There are no methods in this interface , After that, pay attention to type conversion , The return value type of the method is Object , When calling next , We need to convert it to the type of cloned object Then we can print out our cloned objects .
Then talk about the interface , Let's talk about Clonable The problem of deep and shallow copy of interface . As shown in the following code, I cloned an object person2, Access the member variables inside through this object , And changed it , It turns out that the contents of the father will not be changed , A copy like this is a Deep copy .
class Person implements Cloneable {
public String name;
// public Money money = new Money();
public int a = 10;
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
//Object Cloning method of class . All the classes Default inheritance and Object class
@Override
protected Object clone() throws CloneNotSupportedException {
//return super.clone();
return super.clone();
/*Person personClone = (Person) super.clone(); personClone.money = (Money)this.money.clone(); return personClone;*/
}
}
public class TestDemo1 {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person("lmm");
Person person2 = (Person)person.clone();
System.out.println(person.a);//10
System.out.println(person2.a);//10
System.out.println("=========================");
person2.a = 99;
System.out.println(person.a);//10
System.out.println(person2.a);//99
}
}
For example, the following code implementation is a shallow copy , The following code is just Person There is one more member variable Money Class ,Money Class has member variables money = 12.5; Then an object was cloned person2, Access the member variables inside through this object , And changed it , The content of the original father has also been changed . The reason is because ,Person One of the member variables is the reference data type , It also points to an object in the heap , We clone person When the object , The object pointed to by this reference is not cloned , Lead to the parent and cloned objects money All point to the same object , Then we modify the object pointed to by its members through the cloned object , It will also change the content of the father parent .
class Money {
public double money = 12.5;
/* @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }*/
}
class Person implements Cloneable {
public String name;
public Money money = new Money();
public int a = 10;
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
//Object Cloning method of class . All the classes Default inheritance and Object class
@Override
protected Object clone() throws CloneNotSupportedException {
//return super.clone();
return super.clone();
/* Person personClone = (Person) super.clone(); personClone.money = (Money)this.money.clone(); return personClone;*/
}
}
public class TestDemo1 {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person("lmm");
Person person2 = (Person)person.clone();
System.out.println(person.money.money);
System.out.println(person2.money.money);
System.out.println("=========================");
person2.money.money = 99;
System.out.println(person.money.money);
System.out.println(person2.money.money);
}
}
You can also understand it by looking at the figure :
So how to modify and implement deep copy , In this case , First copy out person2, And then person After copying the object pointed to by the reference member variable in the member of person2 Of money Point to the object pointed to by the copied reference Simply put, the copied object and parent have their own member variables , Cannot share member variables , Especially when there are reference data types in member variables . The code is as follows :
class Money implements Cloneable{
public double money = 12.5;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
@Override
protected Object clone() throws CloneNotSupportedException {
//return super.clone();
// return super.clone();
Person personClone = (Person) super.clone();
personClone.money = (Money)this.money.clone();
return personClone;
}
Finally, the following results are achieved :
My first time 1024, Happy holidays, everyone . Thank you for your support 
边栏推荐
- Matlab-其它
- Matlab other
- Longest isometric subsequence
- SQLyog远程连接centos7系统下的MySQL数据库
- On November 24, we celebrate the "full moon"
- Data reverse attack under federated learning -- gradinversion
- Global and Chinese markets of tilting feeders 2022-2028: Research Report on technology, participants, trends, market size and share
- Principes fondamentaux de la théorie musicale (brève introduction)
- Global and Chinese market of wire loop, 2022-2028: Research Report on technology, participants, trends, market size and share
- Opencv's experience of confusing X and Y coordinates
猜你喜欢

STM32疑难杂症之ST-LINK Connection error INVALID ROM TABLE

Fundamentals of music theory (brief introduction)

Real world anti sample attack against semantic segmentation

Vscode下中文乱码问题

2022 Heilongjiang latest food safety administrator simulation exam questions and answers

Matlab数学建模工具

Installation and use of simple packaging tools

SQLyog远程连接centos7系统下的MySQL数据库

OpenCV3 6.3 用滤波器进行缩减像素采样

Intelligent manufacturing solutions digital twin smart factory
随机推荐
How to wrap qstring strings
2022 Heilongjiang latest construction eight members (materialman) simulated examination questions and answers
Development of digital collection trading website development of metauniverse digital collection
Summary of one question per day: linked list (continuously updated)
cve_ 2019_ 0708_ bluekeep_ Rce vulnerability recurrence
Global and Chinese market of snow sweepers 2022-2028: Research Report on technology, participants, trends, market size and share
Specification for package drawing
稀疏矩阵存储
类和对象(类和类的实例化,this,static关键字,封装)
Opencv common method source link (continuous update)
简易打包工具的安装与使用
王-课外单词
Carsim 学习心得-粗略翻译1
How to uninstall SQL Server cleanly
Carsim-问题Failed to start Solver: PATH_ID_OBJ(X) was set to Y; no corresponding value of XXXXX?
Don't know mock test yet? An article to familiarize you with mock
SQLyog远程连接centos7系统下的MySQL数据库
OpenCV3 6.3 用滤波器进行缩减像素采样
力扣每日一题刷题总结:链表篇(持续更新)
Sqlyog remote connection to MySQL database under centos7 system