继承Comparable的实体类
package com.hantao.sortTest;
public class User implements Comparable<Object>{
int id;
String name;
int mainId;
public int getMainId() {
return mainId;
}
public void setMainId(int mainId) {
this.mainId = mainId;
}
public User(int id, String name, int mainId) {
this.id = id;
this.name = name;
this.mainId = mainId;
}
/*
* Getters and Setters
*/
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", mainId=" + mainId +
'}';
}
/**
*负数代表左值小于右值,排在上面
*正数代表左值大于右值,排在下面
*0代表左值等于右值,排在上面
* @param o
* @return
*/
@Override
public int compareTo(Object o) {
//可以这样理解:排序就是比较谁大谁小,将小的放在前面,大的放在后面。
// 例如当返回负数的时候,表明第一个数应该排在第二个数的上面。
//可以按照你想要的规则进行排序,不论是按照集合中的正序(返回值1),
// 还是集合中的倒序(返回值-1)还是按照字典排序(如上)都是可以的。
//1、如果字符串相等返回值0
//2、如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值(ascii码值)(负值代表:前字符串的值小于后字符串,正值代表:前字符串大于后字符串)
//3、如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方全比较完,这时就比较字符的长度.
//负值代表:前字符串的值小于后字符串,正值代表:前字符串大于后字符串
//字符串越小的放在越前面。
//同一个对象
System.out.println("左侧为"+this.toString()+":右侧为"+o.toString());
if(this ==o){
User u = (User) o;
System.out.println("左边==右侧,将"+mainId+"放在"+u.mainId+"前面");
//负数代表左值小于右值,排在上面
//正数代表左值大于右值,排在下面
//0代表左值等于右值,排在上面
return 0;
}
else if (o instanceof User) {
User u = (User) o;
if(id<=u.id){
//(this.id-u.id)为负数 从小到大排序
//想要从小到大排序,修改为(u.id-this.id)为负数
System.out.println( "左边<右侧,将"+mainId+"放在"+u.mainId+"前面");
return -1;
}else{
System.out.println("左边>右侧,将"+u.mainId+"放在"+mainId+"前面");
return 1;
}
}else{
System.out.println("报错");
return -1;
}
}
}
test类
然后写一个Test类进行运行
package com.hantao.sortTest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class UserTest2 {
//编写Comparator,根据User的id对User进行排序
private static final Comparator<User> COMPARATOR = new Comparator<User>() {
public int compare(User o1, User o2) {
return o1.compareTo(o2);//运用User类的compareTo方法比较两个对象
}
};
public static void main(String[] args) {
ArrayList<User> student = new ArrayList<User>();
User user1 = new User(1,"zhongjingzou",1);
User user5 = new User(2,"zhongjingzou4",4);
User user4 = new User(2,"zhongjingzou3",3);
User user2 = new User(2,"zhongjingzou2",2);
User user6 =user5;
User user7 =user5;
student.add(user1);
student.add(user5);
student.add(user2);
student.add(user4);
student.add(user7);
student.add(user6);
Collections.sort(student, COMPARATOR);
for(int i=0;i<student.size();i++){
System.out.println(student.get(i).toString());
}
Collections.sort(student,new Comparator<User>() {
@Override
public int compare(User u1, User u2) {
//先倒序排序(从大到小)左边的参数和右边的参数相对传入的顺序倒置
int fileType = u2.getId() - u1.getId();
//想要正序排列(从小到大) 左边的参数和右边的参数按照传入的顺序
//int fileType = u1.getId() - u2.getId();
if (fileType == 0) {
//1、如果字符串相等返回值0
//2、如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值(ascii码值)(负值代表:前字符串的值小于后字符串,正值代表:前字符串大于后字符串)
//3、如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方全比较完,这时就比较字符的长度.
//负值代表:前字符串的值小于后字符串,正值代表:前字符串大于后字符串
//字符串越小的放在越前面。
return u1.getName().compareToIgnoreCase(u2.getName());
}
return fileType;
}
});
for(int i=0;i<student.size();i++){
System.err.println(student.get(i).toString());
}
}
}
个人理解:
返回值的正,负,0
*负数代表左值小于右值,左值插入到当前右值的上面(前面) *正数代表左值大于右值,右值插入到当前左值的上面(前面) *0代表左值等于右值,左值插入到当前右值的上面(前面)
测试1:
首先我们来查看一下
//编写Comparator,根据User的id对User进行排序
private static final Comparator<User> COMPARATOR = new Comparator<User>() {
public int compare(User o1, User o2) {
return o1.compareTo(o2);//运用User类的compareTo方法比较两个对象
}
};
的效果。
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=1, name='zhongjingzou', mainId=1}
左边>右侧,将1放在4前面
Disconnected from the target VM, address: '127.0.0.1:56748', transport: 'socket'
左侧为User{id=2, name='zhongjingzou2', mainId=2}:右侧为User{id=2, name='zhongjingzou4', mainId=4}
左边<右侧,将2放在4前面
左侧为User{id=2, name='zhongjingzou2', mainId=2}:右侧为User{id=2, name='zhongjingzou4', mainId=4}
左边<右侧,将2放在4前面
左侧为User{id=2, name='zhongjingzou2', mainId=2}:右侧为User{id=1, name='zhongjingzou', mainId=1}
左边>右侧,将1放在2前面
左侧为User{id=2, name='zhongjingzou3', mainId=3}:右侧为User{id=2, name='zhongjingzou2', mainId=2}
左边<右侧,将3放在2前面
左侧为User{id=2, name='zhongjingzou3', mainId=3}:右侧为User{id=1, name='zhongjingzou', mainId=1}
左边>右侧,将1放在3前面
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=2, name='zhongjingzou2', mainId=2}
左边<右侧,将4放在2前面
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=2, name='zhongjingzou3', mainId=3}
左边<右侧,将4放在3前面
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=1, name='zhongjingzou', mainId=1}
左边>右侧,将1放在4前面
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=2, name='zhongjingzou3', mainId=3}
左边<右侧,将4放在3前面
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=2, name='zhongjingzou4', mainId=4}
左边==右侧,将4放在4前面
User{id=1, name='zhongjingzou', mainId=1}
User{id=2, name='zhongjingzou4', mainId=4}
User{id=2, name='zhongjingzou4', mainId=4}
User{id=2, name='zhongjingzou3', mainId=3}
User{id=2, name='zhongjingzou2', mainId=2}
User{id=2, name='zhongjingzou4', mainId=4}
可以根据描述的语句自己动手一下,看一下写的顺序是否一致。
然后修改一下list中add的顺序,可以发现相等的
student.add(user1);
student.add(user2);
student.add(user4);
student.add(user5);
student.add(user6);
student.add(user7);
左侧为User{id=2, name='zhongjingzou2', mainId=2}:右侧为User{id=1, name='zhongjingzou', mainId=1}
左边>右侧,将1放在2前面
左侧为User{id=2, name='zhongjingzou3', mainId=3}:右侧为User{id=2, name='zhongjingzou2', mainId=2}
左边<右侧,将3放在2前面
左侧为User{id=2, name='zhongjingzou3', mainId=3}:右侧为User{id=2, name='zhongjingzou2', mainId=2}
左边<右侧,将3放在2前面
左侧为User{id=2, name='zhongjingzou3', mainId=3}:右侧为User{id=1, name='zhongjingzou', mainId=1}
左边>右侧,将1放在3前面
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=2, name='zhongjingzou3', mainId=3}
左边<右侧,将4放在3前面
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=1, name='zhongjingzou', mainId=1}
左边>右侧,将1放在4前面
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=2, name='zhongjingzou3', mainId=3}
左边<右侧,将4放在3前面
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=2, name='zhongjingzou4', mainId=4}
左边==右侧,将4放在4前面
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=2, name='zhongjingzou4', mainId=4}
左边==右侧,将4放在4前面
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=2, name='zhongjingzou2', mainId=2}
左边<右侧,将4放在2前面
左侧为User{id=2, name='zhongjingzou4', mainId=4}:右侧为User{id=2, name='zhongjingzou3', mainId=3}
左边<右侧,将4放在3前面
User{id=1, name='zhongjingzou', mainId=1}
User{id=2, name='zhongjingzou4', mainId=4}
User{id=2, name='zhongjingzou4', mainId=4}
User{id=2, name='zhongjingzou4', mainId=4}
User{id=2, name='zhongjingzou3', mainId=3}
User{id=2, name='zhongjingzou2', mainId=2}
修改add的顺序可以发现输出的结构有差异。
相同的对象(地址值一样)在list中的位置不一致也将导致排序的问题出现。
测试2:
然后来看一下
Collections.sort(student,new Comparator<User>() {
@Override
public int compare(User u1, User u2) {
//先倒序排序(从大到小)左边的参数和右边的参数相对传入的顺序倒置
int fileType = u2.getId() - u1.getId();
//想要正序排列(从小到大) 左边的参数和右边的参数按照传入的顺序
//int fileType = u1.getId() - u2.getId();
if (fileType == 0) {
//1、如果字符串相等返回值0
//2、如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值(ascii码值)(负值代表:前字符串的值小于后字符串,正值代表:前字符串大于后字符串)
//3、如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方全比较完,这时就比较字符的长度.
//负值代表:前字符串的值小于后字符串,正值代表:前字符串大于后字符串
//字符串越小的放在越前面。
return u1.getName().compareToIgnoreCase(u2.getName());
}
return fileType;
}
});
对应的结果
student.add(user1); student.add(user2); student.add(user4); student.add(user5); student.add(user6); student.add(user7);
结果如下:
User{id=2, name='zhongjingzou2', mainId=2}
User{id=2, name='zhongjingzou3', mainId=3}
User{id=2, name='zhongjingzou4', mainId=4}
User{id=2, name='zhongjingzou4', mainId=4}
User{id=2, name='zhongjingzou4', mainId=4}
User{id=1, name='zhongjingzou', mainId=1}
student.add(user1); student.add(user5); student.add(user2); student.add(user4); student.add(user7); student.add(user6);
结果如下:
User{id=2, name='zhongjingzou2', mainId=2}
User{id=2, name='zhongjingzou3', mainId=3}
User{id=2, name='zhongjingzou4', mainId=4}
User{id=2, name='zhongjingzou4', mainId=4}
User{id=2, name='zhongjingzou4', mainId=4}
User{id=1, name='zhongjingzou', mainId=1}
两次结果一致,可以思考一下为何这次add的顺序并没有导致之前相同地址值的排序sort出异常的情况。
附上相关int类型测试sort方法的测试Demo
import java.util.*;
public class SortTest {
public void arraySort(){
int[] arr = {1,4,6,333,8,2};
Arrays.sort(arr);//使用java.util.Arrays对象的sort方法
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
public void listSort1(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(55);
list.add(9);
list.add(0);
list.add(2);
Collections.sort(list);//使用Collections的sort方法
for(int a :list){
System.out.println(a);
}
}
//对list降序排序
public void listSort2(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(55);
list.add(9);
list.add(0);
list.add(2);
//升序排列
Collections.sort(list, new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});//使用Collections的sort方法,并且重写compare方法
for(int a :list){
System.out.println(a);
}
//降序排列
System.out.println("从大到小");
Collections.sort(list, new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});//使用Collections的sort方法,并且重写compare方法
for(int a :list){
System.out.println(a);
}
}
}
错误示例: 永远无法返回正值,永远只返回负值,无法正常排序。
照这么比,o1永远比o2要小那当然不能排序。
package com.lin;
import java.util.Comparator;
public class ComparatorTest implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
if(o1.getAge() < o2.getAge()){
int num = o1.getAge() - o2.getAge();
// System.out.println(num);
return num;
}else{
int num = o2.getAge() - o1.getAge();
// System.out.println(num);
return num;
}
}
}
相关:
【转】Java中Collections.sort()和Arrays.sort()所采用的排序算法
https://www.cnblogs.com/merru/articles/4666493.html