对list中的对象进行排序

时间:2025-03-16 08:31:02

list的排序分为两大类:

一种是针对简单的包装类型进行排序,即list中存放的String或者Integer类型

另一种是针对自定义的对象类型进行排序,对象需要像包装类型一样去实现Comparable接口,然后重写CompareTo方法

一、针对简单包装类型进行排序

package ;

import ;
import ;
import ;

/**
 * @author hungteshun
 * @description: 对String类型、Integer类型进行排序
 * @date 2018/11/29 16:45
 */
public class EasySort {

    public static void main(String[] args) {
        List<String> stringList = new ArrayList<>();
        ("张三");
        ("李四");
        ("王五");
        ("赵六");
        ("排序之前的顺序:" + stringList );
        (stringList);
        ("排序之后的顺序:" + stringList );
        /**
         * 注意这个reserve方法,是反转,而不是在无序的前提下直接倒序
         */
        (stringList);
        ("反转之后的顺序:" + stringList );

        List<Integer> integerList = new ArrayList<>();
        (2);
        (1);
        (9);
        (5);
        (12);
        (20);
        ("排序之前的顺序" + integerList);
        (integerList);
        ("排序之后的顺序" + integerList);
        /**
         * 注意这个reserve方法,是反转,而不是在无序的前提下直接倒序
         */
        (integerList);
        ("反转之后的顺序:" + integerList );
    }
}

输出结果如下:

排序之前的顺序:[张三, 李四, 王五, 赵六]
排序之后的顺序:[张三, 李四, 王五, 赵六]
反转之后的顺序:[赵六, 王五, 李四, 张三]
排序之前的顺序[2, 1, 9, 5, 12, 20]
排序之后的顺序[1, 2, 5, 9, 12, 20]
反转之后的顺序:[20, 12, 9, 5, 2, 1]

查看String类的源代码,String类也实现了Comparable<String>接口,查看其重写的compareTo()方法源码:

public int compareTo(String anotherString) {
	int len1 = ;
	int len2 = ;
	int lim = (len1, len2);
	char v1[] = value;
	char v2[] = ;

	int k = 0;
	while (k < lim) {
		char c1 = v1[k];
		char c2 = v2[k];
		if (c1 != c2) {
			return c1 - c2;
		}
		k++;
	}
	return len1 - len2;
}

二、针对list中的对象按照某个属性进行排序

2.1、对象实现Comparable接口

新建对象的时候需要实现Comparable接口,然后重写CompareTo方法。

创建一个Student对象:

package ;

/**
 * @author hungteshun
 * @description:
 * @date 2018/11/29 19:58
 */
public class Student implements Comparable<Student> {

    private Integer age;
    private Integer score;
    private String name;

    public Student() {
    }

    public Student(Integer age, Integer score, String name) {
         = age;
         = score;
         = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
         = age;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
         = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
         = name;
    }

    @Override
    public int compareTo(Student o) {
        //先按照年龄排序
        Integer i = (());
        if (i == 0) {
            //如果年龄相等,则按照分数排序
            i = (());
            if (i == 0) {
                //如果分数相等,则按照姓名排序
                i = ().compareTo(());
            }
        }
        /**
         * i等于0的时候表示相等;
         * i等于1的时候表示大于;
         * i等于-1的时候表示小于;
         */
        return i;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", score=" + score +
                ", name='" + name + '\'' +
                '}';
    }
}

查看一下Integer类的compareTo()方法的实现源码:

public int compareTo(Integer anotherInteger) {
	return compare(, );
}

继续查看compare()方法:

public static int compare(int x, int y) {
	return (x < y) ? -1 : ((x == y) ? 0 : 1);
}

* i等于-1的时候表示小于;
* i等于0的时候表示相等;
* i等于1的时候表示大于;

对该对象的集合进行排序

package ;

import ;

import ;
import ;
import ;
import ;

/**
 * @author hungteshun
 * @description:
 * @date 2018/11/29 19:56
 */
public class StudentSort {

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        (new Student(23, 90, "张三"));
        (new Student(22, 97, "李四"));
        (new Student(23, 95, "王五"));
        (new Student(24, 91, "赵六"));
        (new Student(21, 98, "赵六"));
        (new Student(21, 98, "赵五"));
        (new Student(21, 98, "赵七"));
        ("排序之前的list:");
        ().forEach(::println);
        //(studentList);
        //("排序之后的list:");
        //().forEach(::println);
        //使用lambda表达式的sort是一样的效果
        ("使用lambda表达式排序之后的list:");
        ().sorted().forEach(::println);
    }

}

输出结果:

排序之前的list:
Student{age=23, score=90, name='张三'}
Student{age=22, score=97, name='李四'}
Student{age=23, score=95, name='王五'}
Student{age=24, score=91, name='赵六'}
Student{age=21, score=98, name='赵六'}
Student{age=21, score=98, name='赵五'}
Student{age=21, score=98, name='赵七'}
使用lambda表达式排序之后的list:
Student{age=21, score=98, name='赵七'}
Student{age=21, score=98, name='赵五'}
Student{age=21, score=98, name='赵六'}
Student{age=22, score=97, name='李四'}
Student{age=23, score=90, name='张三'}
Student{age=23, score=95, name='王五'}
Student{age=24, score=91, name='赵六'}

2.2、使用Comparator接口

Studen对象不用实现Comparable接口

package ;

/**
 * @author hungteshun
 * @description:
 * @date 2018/11/29 19:58
 */
public class Student {

    private Integer age;
    private Integer score;
    private String name;

    public Student() {
    }

    public Student(Integer age, Integer score, String name) {
         = age;
         = score;
         = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
         = age;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
         = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
         = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", score=" + score +
                ", name='" + name + '\'' +
                '}';
    }
}

对该对象的集合进行排序

package ;

import ;

import ;
import ;
import ;
import ;

/**
 * @author hungteshun
 * @description:
 * @date 2018/11/29 19:56
 */
public class StudentSort {

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        (new Student(23, 90, "张三"));
        (new Student(22, 97, "李四"));
        (new Student(23, 95, "王五"));
        (new Student(24, 91, "赵六"));
        (new Student(21, 98, "赵六"));
        (new Student(21, 98, "赵五"));
        (new Student(21, 98, "赵七"));
        ("排序之前的list:");
        ().forEach(::println);
        (studentList, (o1, o2) -> {
            //先按照年龄排序
            Integer i = ().compareTo(());
            if (i == 0) {
                //如果年龄相等,则按照分数排序
                i = ().compareTo(());
                if (i == 0) {
                    //如果分数相等,则按照姓名排序
                    i = ().compareTo(());
                }
            }
            return i;
        });
        ("排序之后的list:");
        ().forEach(::println);

        //只按照年龄排序方式一:
        (studentList, (e1, e2) -> ().compareTo(()));
        //只按照年龄排序方式二:
        (studentList, (Student::getAge));
        ("只按照年龄排序之后的list:");
        ().forEach(::println);
        //只按照姓名排序方式一:
        (studentList, (e1, e2) -> ().compareTo(()));
        //只按照姓名排序方式二:
        (studentList, (Student::getName));
        //只按照姓名排序方式三:
        (studentList, (e -> ()));
        //只按照姓名排序方式四:
        ((e1, e2) -> ().compareTo(()));
        //只按照姓名排序方式五:
        ((Student::getName));
        //只按照姓名排序方式六:
        ((e -> ()));
    }

}

输出结果:

排序之前的list:
Student{age=23, score=90, name='张三'}
Student{age=22, score=97, name='李四'}
Student{age=23, score=95, name='王五'}
Student{age=24, score=91, name='赵六'}
Student{age=21, score=98, name='赵六'}
Student{age=21, score=98, name='赵五'}
Student{age=21, score=98, name='赵七'}
排序之后的list:
Student{age=21, score=98, name='赵七'}
Student{age=21, score=98, name='赵五'}
Student{age=21, score=98, name='赵六'}
Student{age=22, score=97, name='李四'}
Student{age=23, score=90, name='张三'}
Student{age=23, score=95, name='王五'}
Student{age=24, score=91, name='赵六'}
只按照年龄排序之后的list:
Student{age=21, score=98, name='赵七'}
Student{age=21, score=98, name='赵五'}
Student{age=21, score=98, name='赵六'}
Student{age=22, score=97, name='李四'}
Student{age=23, score=90, name='张三'}
Student{age=23, score=95, name='王五'}
Student{age=24, score=91, name='赵六'}
只按照姓名排序之后的list:
Student{age=23, score=90, name='张三'}
Student{age=22, score=97, name='李四'}
Student{age=23, score=95, name='王五'}
Student{age=21, score=98, name='赵七'}
Student{age=21, score=98, name='赵五'}
Student{age=21, score=98, name='赵六'}
Student{age=24, score=91, name='赵六'}

三、使用泛型对任何属性进行排序

定义一个UserInfo对象

package ;

import ;
import ;

import ;
import ;
import ;

/**
 * @author hungteshun
 * @description:
 * @date 2018/11/31 22:21
 */
@Getter
@Setter
@ToString
public class UserInfo {

    private Long userId;

    private String userName;

    private String password;

    private Date birthday;

    private Integer sex;

    private Integer age;

    public String getBirthdayStr(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return (getBirthday());
    }
}

然后创建一个工具类

package ;

import ;
import ;
import ;
import ;
import ;

import ;

/**
 * @author hungteshun
 * @description:
 * @date 2018/11/31 22:23
 */
public class SortListUtil<E> {

    public void Sort(List<E> list, final String method, final String order) {
        (list, new Comparator<E>() {
            @Override
            public int compare(E o1, E o2) {
                int ret = 0;
                try {
                    Method method1 = ().getMethod(method, null);
                    Method method2 = ().getMethod(method, null);
                    //倒序
                    if ((order) && "desc".equalsIgnoreCase(order)) {
                        ret = (o2, null).toString().compareTo((o1, null)
                                .toString());
                    }
                    else {
                        ret = (o1, null).toString()
                                .compareTo((o2, null).toString());
                    }

                } catch (NoSuchMethodException e) {
                    ();
                } catch (IllegalAccessException e) {
                    ();
                } catch (InvocationTargetException e) {
                    ();
                }
                return ret;
            }
        });
    }
}

主方法中调用

package ;

import ;
import ;
import ;
import ;
import ;

import ;
import ;

/**
 * @author hungteshun
 * @description: 
 * @date 2018/11/31 22:15:30
 */
public class App {
    public static void main(String[] args) throws ParseException {
        List<UserInfo> userInfos = new ArrayList<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        UserInfo userInfo = new UserInfo();
        (2L);
        ("b");
        (10);
        (("2000-10-01"));
        (userInfo);

        userInfo = new UserInfo();
        (1L);
        ("c");
        (30);
        (("1980-10-01"));
        (userInfo);

        userInfo = new UserInfo();
        (3L);
        ("a");
        (20);
        (("1990-10-01"));
        (userInfo);

        SortListUtil<UserInfo> sortList = new SortListUtil<UserInfo>();

        ("==========原来的顺序==========");
        for (Iterator<UserInfo> iterator = (); (); ) {
            UserInfo userInfo1 = ();
            (userInfo1);
        }

        ("==========按照userId排序==========");

        (userInfos, "getUserId", null);
        for (Iterator<UserInfo> iterator = (); (); ) {
            UserInfo userInfo1 = ();
            (userInfo1);
        }

        ("==========按照userName倒序排序==========");
        (userInfos, "getUserName", "desc");
        for (Iterator<UserInfo> iterator = (); (); ) {
            UserInfo userInfo1 = ();
            (userInfo1);
        }

        //这里按照日期排序是默认按照星期进行排序,因此我们需要对返回的日期格式进行手动格式化成yyyy-MM-dd类型
        ("==========按照birthday排序==========");
        (userInfos, "getBirthday", null);
        for (Iterator<UserInfo> iterator = (); (); ) {
            UserInfo userInfo1 = ();
            (userInfo1);
        }

        ("==========按照birthdayStr排序==========");
        (userInfos, "getBirthdayStr", null);
        for (UserInfo userInfo1 : userInfos) {
            (userInfo1);
        }

    }

}