String类的Comparable接口
1 、String 类实现了Comparable < String > 接口,并提供了compareTo方法的实现,因此,字符串对象(即String 类型的实例)可以直接调用compareTo ( ) 方法来比较它们。2 、String 类的compareTo ( ) 方法是这样工作的:它按照字典顺序比较两个字符串,从两个字符串的第一个字符开始比较,如果它们相等,则继续比较下一个字符,直到找到不同的字符或者到达字符串的末尾,如果所有的字符都相同,那么较短的字符串被认为是较小的。
排序
Comparable接口
"实现Comparable接口 ,就必须重写它的compareTo()方法" "Comparable接口" 是一个泛型接口,在类的声明中使用泛型参数,来指定需要比较的对象类型,它包含一个compareTo ( ) 方法,如下所示:public interface Comparable < T > { int compareTo ( T o) ; } "compareTo()方法" ,返回一个整数值,用于表示当前对象,与另一个对象的比较结果。通常,它有以下三种返回值:如果,当前对象 小于 另一个对象,则返回,负整数。如果,当前对象 等于 另一个对象,则返回,零。如果,当前对象 大于 另一个对象,则返回,正整数。使用的场景:1 、具体的类A ,实现Comparable 接口2 、重写Comparable 接口中的compareTo ( Object obj) 方法,在此方法中指明比较类A 的对象的大小的标准3 、创建类A 的多个实例,进行大小的比较或排序。
实现Comparable接口
要使一个类可以进行自然排序,需要实现"Comparable接口" 并提供"compareTo()方法的具体实现" ,在compareTo ( ) 方法中,你需要指定对象之间的比较规则,如:
"Student.java"
public 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 other) { return this . age - other. age; } public String toString ( ) { return "Student{name='" + name + "', age=" + age + '}' ; }
}
Student 类实现了Comparable < Student > 接口,并重写了compareTo ( ) 方法,按照年龄升序排序,是通过比较当前对象的年龄属性和另一个对象的年龄属性来实现的。"MyTest.java"
import java. util. TreeSet ;
public class MyTest { public static void main ( String [ ] args) { TreeSet < Student > studentSet = new TreeSet < > ( ) ; studentSet. add ( new Student ( "Alice" , 22 ) ) ; studentSet. add ( new Student ( "Bob" , 20 ) ) ; studentSet. add ( new Student ( "Charlie" , 25 ) ) ; for ( Student student : studentSet) { System . out. println ( student) ; } }
}
"对上面的代码做一下解释" 在Java 中,当你创建一个实现了Comparable 接口的类的实例,并将其放入一个TreeSet 集合时,TreeSet 会自动使用该类实现的compareTo ( ) 方法来对集合中的元素进行排序,你不需要显式地调用compareTo ( ) 方法,因为,TreeSet 内部在需要时会自动调用它。另:1 、创建TreeSet 实例:当你创建 "TreeSet<Student> studentSet" 时,实际上是在告诉Java 你想要一个有序的、不重复的集合,该集合将包含Student 类型的对象。2 、添加元素到TreeSet :当你调用 "studentSet.add(new Student(" Alice ", 22))" 等方法添加元素时,TreeSet 内部会检查新元素与集合中已存在元素的顺序关系,这是通过调用新元素的compareTo方法实现的。3 、自动排序:在TreeSet 内部,元素是以红黑树的结构存储的,当你添加一个新元素时,TreeSet 会使用compareTo ( ) 方法来确定新元素在树中的正确位置,以保持集合的有序性,这个过程是自动的,你不需要显式地调用任何排序方法。4 、遍历TreeSet :当你遍历TreeSet 时(使用for - each循环),你会看到元素已经按照compareTo方法定义的顺序排列好了。这个例子中,Student 类实现了Comparable < Student > 接口,并重写了compareTo方法,该方法比较两个Student 对象的age属性,因此,当你将Student 对象添加到TreeSet 时,它们会按照年龄升序排列。
Collections.sort
"Student.java"
public 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 other) { return this . age - other. age; } public String toString ( ) { return "Student{name='" + name + "', age=" + age + '}' ; }
} import java. util. ArrayList ;
import java. util. Collections ;
import java. util. List ;
public class Test1 { public static void main ( String [ ] args) { List < Student > list = new ArrayList < > ( ) ; list. add ( new Student ( "Alice" , 22 ) ) ; list. add ( new Student ( "White" , 18 ) ) ; list. add ( new Student ( "Black" , 30 ) ) ; Collections . sort ( list) ; for ( Student stu : list) { System . out. println ( stu) ; } }
} 为什么 Collections . sort ( list) 会使用 Student 类的compareTo ( ) 方法进行排序呢?因为,Student 类实现了Comparable < Student > 接口并重写了compareTo ( ) 方法,所以,当你调用 Collections . sort ( list) 时,该方法会自动调用,Student 类中的compareTo ( ) 方法,来比较对象并进行排序。
自定义排序
"要求" 有时,需要对对象进行多属性排序,例如,先按年龄升序排序,然后按姓名字母顺序排序,为了实现多属性排序,可以在 compareTo ( ) 方法中逐一比较不同属性,确保按照所需顺序比较。"Person.java"
public class Person implements Comparable < Person > { String name; int age; public Person ( String name, int age) { this . name = name; this . age = age; } @Override public int compareTo ( Person other) { int ageComparison = this . age - other. age; if ( ageComparison != 0 ) { return ageComparison; } return this . name. compareTo ( other. name) ; } @Override public String toString ( ) { return "Student{name='" + name + "', age=" + age + '}' ; }
} import java. util. Collections ;
import java. util. List ;
public class PersonTest { public static void main ( String [ ] args) { List < Person > list = new ArrayList < > ( ) ; list. add ( new Person ( "Wang" , 26 ) ) ; list. add ( new Person ( "King" , 19 ) ) ; list. add ( new Person ( "He" , 19 ) ) ; list. add ( new Person ( "Black" , 28 ) ) ; Collections . sort ( list) ; for ( Person per : list) { System . out. println ( per) ; } }
}
Comparator定制排序
什么时候使用?当,元素的类型没有实现java. lang. Comparable 接口,而又不方便修改代码( 比如JDK 当中的类) ,或者,实现了java. lang. Comparable 接口,但定义好的排序规则不适合当前的操作,那么,可以考虑使用接口Comparator 的对象来排序,强行对多个对象进行整体排序的比较。1 、public interface Comparator < T > Comparator 属于接口且支持范型,位于java. util包下2 、Comparator 接口,内置实现自定义排序的抽象方法compare ( ) ,int compare ( T o1, T o2) ,T :泛型,这个方法是让两个形参对象去比较大小。重写compare ( Object o1, Object o2) 方法,比较o1和o2的大小:如果,返回,正整数,则表示o1大于o2如果,返回0 ,表示相等如果,返回负整数,表示 o1小于o2需要在compare中指明o1和o2按照什么规则比较3 、可以将Comparator 传递给sort方法(如 Collections . sort或Arrays . sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有序set 或 有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
Arrays类下的sort方法
public static < T > void sort ( T [ ] a, Comparator < ? super T > c)
对基本数据类型的排序
import java. util. Arrays ;
import java. util. Comparator ; public class TestComparator { public static void main ( String [ ] args) { Integer [ ] arr1 = { 1 , 4 , 2 , 3 } ; Arrays . sort ( arr1, new Comparator < Integer > ( ) { @Override public int compare ( Integer o1, Integer o2) { return o2 - o1; } } ) ; System . out. println ( Arrays . toString ( arr1) ) ; Arrays . sort ( arr1, new Comparator < Integer > ( ) { @Override public int compare ( Integer o1, Integer o2) { return o1 - o2; } } ) ; System . out. println ( Arrays . toString ( arr1) ) ; }
}
对象数组的排序
"StuComparator.java"
public class StuComparator { String name; int age; double height; public StuComparator ( ) { } public StuComparator ( String name, int age, double height) { this . name = name; this . age = age; this . height = height; } 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 getHeight ( ) { return height; } public void setHeight ( double height) { this . height = height; } @Override public String toString ( ) { return "\n" + "name=" + name + ", age=" + age + ", height=" + height + " \n" ; }
} "TestStuComparator.java"
import java. util. Arrays ;
import java. util. Comparator ;
public class TestStuComparator { public static void main ( String [ ] args) { StuComparator [ ] stu = new StuComparator [ 4 ] ; stu[ 0 ] = new StuComparator ( "张三" , 16 , 176.6 ) ; stu[ 1 ] = new StuComparator ( "李四" , 25 , 181.3 ) ; stu[ 2 ] = new StuComparator ( "小明" , 18 , 179.4 ) ; stu[ 3 ] = new StuComparator ( "小红" , 17 , 165 ) ; Arrays . sort ( stu, new Comparator < StuComparator > ( ) { @Override public int compare ( StuComparator o1, StuComparator o2) { return o1. age - o2. age; } } ) ; System . out. println ( Arrays . toString ( stu) ) ; Arrays . sort ( stu, new Comparator < StuComparator > ( ) { @Override public int compare ( StuComparator o1, StuComparator o2) { return Double . compare ( o1. height, o2. height) ; } } ) ; System . out. println ( Arrays . toString ( stu) ) ; }
}