对list中的对象进行排序

本文深入讲解Java中List的排序方法,包括对简单包装类型如String和Integer的排序,以及自定义对象类型的排序策略。探讨了实现Comparable接口和使用Comparator接口进行排序的细节,并提供了丰富的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

list的排序分为两大类:

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

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

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

package com.hungteshun;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @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.add("张三");
        stringList.add("李四");
        stringList.add("王五");
        stringList.add("赵六");
        System.out.println("排序之前的顺序:" + stringList );
        Collections.sort(stringList);
        System.out.println("排序之后的顺序:" + stringList );
        /**
         * 注意这个reserve方法,是反转,而不是在无序的前提下直接倒序
         */
        Collections.reverse(stringList);
        System.out.println("反转之后的顺序:" + stringList );

        List<Integer> integerList = new ArrayList<>();
        integerList.add(2);
        integerList.add(1);
        integerList.add(9);
        integerList.add(5);
        integerList.add(12);
        integerList.add(20);
        System.out.println("排序之前的顺序" + integerList);
        Collections.sort(integerList);
        System.out.println("排序之后的顺序" + integerList);
        /**
         * 注意这个reserve方法,是反转,而不是在无序的前提下直接倒序
         */
        Collections.reverse(integerList);
        System.out.println("反转之后的顺序:" + 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 = value.length;
	int len2 = anotherString.value.length;
	int lim = Math.min(len1, len2);
	char v1[] = value;
	char v2[] = anotherString.value;

	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 com.hungteshun.domain;

/**
 * @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) {
        this.age = age;
        this.score = score;
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

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

    public Integer getScore() {
        return score;
    }

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

    public String getName() {
        return name;
    }

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

    @Override
    public int compareTo(Student o) {
        //先按照年龄排序
        Integer i = this.age.compareTo(o.getAge());
        if (i == 0) {
            //如果年龄相等,则按照分数排序
            i = this.score.compareTo(o.getScore());
            if (i == 0) {
                //如果分数相等,则按照姓名排序
                i = this.getName().compareTo(o.getName());
            }
        }
        /**
         * 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(this.value, anotherInteger.value);
}

继续查看compare()方法:

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

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

对该对象的集合进行排序

package com.hungteshun;

import com.hungteshun.domain.Student;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

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

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

/**
 * @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) {
        this.age = age;
        this.score = score;
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

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

    public Integer getScore() {
        return score;
    }

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

    public String getName() {
        return name;
    }

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

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

对该对象的集合进行排序

package com.hungteshun;

import com.hungteshun.domain.Student;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

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

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

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

}

输出结果:

排序之前的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 com.hungteshun.entity;

import java.text.SimpleDateFormat;
import java.util.Date;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * @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 sdf.format(getBirthday());
    }
}

然后创建一个工具类

package com.hungteshun.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.apache.commons.lang.StringUtils;

/**
 * @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) {
        Collections.sort(list, new Comparator<E>() {
            @Override
            public int compare(E o1, E o2) {
                int ret = 0;
                try {
                    Method method1 = o1.getClass().getMethod(method, null);
                    Method method2 = o2.getClass().getMethod(method, null);
                    //倒序
                    if (StringUtils.isNotEmpty(order) && "desc".equalsIgnoreCase(order)) {
                        ret = method2.invoke(o2, null).toString().compareTo(method1.invoke(o1, null)
                                .toString());
                    }
                    else {
                        ret = method1.invoke(o1, null).toString()
                                .compareTo(method2.invoke(o2, null).toString());
                    }

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

主方法中调用

package com.hungteshun;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.hungteshun.entity.UserInfo;
import com.hungteshun.util.SortListUtil;

/**
 * @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();
        userInfo.setUserId(2L);
        userInfo.setUserName("b");
        userInfo.setAge(10);
        userInfo.setBirthday(format.parse("2000-10-01"));
        userInfos.add(userInfo);

        userInfo = new UserInfo();
        userInfo.setUserId(1L);
        userInfo.setUserName("c");
        userInfo.setAge(30);
        userInfo.setBirthday(format.parse("1980-10-01"));
        userInfos.add(userInfo);

        userInfo = new UserInfo();
        userInfo.setUserId(3L);
        userInfo.setUserName("a");
        userInfo.setAge(20);
        userInfo.setBirthday(format.parse("1990-10-01"));
        userInfos.add(userInfo);

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

        System.out.println("==========原来的顺序==========");
        for (Iterator<UserInfo> iterator = userInfos.iterator(); iterator.hasNext(); ) {
            UserInfo userInfo1 = iterator.next();
            System.out.println(userInfo1);
        }

        System.out.println("==========按照userId排序==========");

        sortList.Sort(userInfos, "getUserId", null);
        for (Iterator<UserInfo> iterator = userInfos.iterator(); iterator.hasNext(); ) {
            UserInfo userInfo1 = iterator.next();
            System.out.println(userInfo1);
        }

        System.out.println("==========按照userName倒序排序==========");
        sortList.Sort(userInfos, "getUserName", "desc");
        for (Iterator<UserInfo> iterator = userInfos.iterator(); iterator.hasNext(); ) {
            UserInfo userInfo1 = iterator.next();
            System.out.println(userInfo1);
        }

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

        System.out.println("==========按照birthdayStr排序==========");
        sortList.Sort(userInfos, "getBirthdayStr", null);
        for (UserInfo userInfo1 : userInfos) {
            System.out.println(userInfo1);
        }

    }

}

 

可以使用Comparator接口来对List中的对象的属性进行排序,具体步骤如下: 1. 定义一个实现了Comparator接口的类,重写compare方法,在方法中比较两个对象的属性值,返回一个int值,表示比较结果。 例如,对一个Person类的年龄进行排序,可以定义一个AgeComparator类: ``` public class AgeComparator implements Comparator<Person> { @Override public int compare(Person p1, Person p2) { return p1.getAge() - p2.getAge(); } } ``` 2. 在需要排序的代码中,调用Collections.sort方法,并将Comparator对象作为参数传入。 例如,对一个List<Person> list进行年龄排序,可以这样写: ``` Collections.sort(list, new AgeComparator()); ``` 完整示例代码: ``` import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class Main { public static void main(String[] args) { List<Person> list = new ArrayList<>(); list.add(new Person("Tom", 20)); list.add(new Person("Jerry", 18)); list.add(new Person("Mike", 25)); list.add(new Person("Alice", 22)); Collections.sort(list, new AgeComparator()); for (Person p : list) { System.out.println(p.getName() + " " + p.getAge()); } } static class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } } static class AgeComparator implements Comparator<Person> { @Override public int compare(Person p1, Person p2) { return p1.getAge() - p2.getAge(); } } } ``` 输出结果: ``` Jerry 18 Tom 20 Alice 22 Mike 25 ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值