Java List, Map和自定义Class的排序

本文深入讲解如何使用Collections.sort方法对Java中的List、Map以及自定义Class进行高效排序,包括正序、逆序及自定义排序策略,适用于不同数据类型的排序需求。

摘要

本文主要介绍利用Collections.sort方法对list, map和自定义的class进行排序。

基本方法

  • 方法1

    利用public static <T extends Comparable<? super T>> void sort(List<T> list)排序方法,则List中的元素对应的class需要implements Comparable接口,实现public int compareTo(T o)方法

  • 方法2

    利用public static <T> void sort(List<T> list, Comparator<? super T> c)排序方法,则需要新建一个Comparator类,重写compare方法。

具体操作

List排序

直接构造单测样例,List元素分别使用Integer和String为例进行验证,其中Integer和String均实现 Comparable接口的public int compareTo(T o)方法。样例通过新建Comparator类,实现了Integer正序和逆序排列,字符串根据长度排序。

package hello.core.sort;
import org.junit.Test;
import java.util.*;

/**
 * 排序测试
 *
 * Created on 2018/8/16.
 *
 * @author eyangmeng@163.com
 */
public class SortUtilsTest {

    /**
     * List元素类型为Integer测试
     *
     * @throws Exception 异常出现
     */
    @Test
    public void testIntegerListSort() throws Exception {
        // number
        Integer [] numbers = {1, 3, 5, 7, 11, 13, 14, 31};
        List<Integer> list = Arrays.asList(numbers);

        // 正序
        Collections.sort(list);
        System.out.println(list);

        // 逆序
        Collections.sort(list, new Comparator<Integer>() {
            // 构造逆序的compare
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);
            }
        });
        System.out.println(list);
    }

    /**
     * List元素类型为String测试
     *
     * @throws Exception 异常出现
     */
    @Test
    public void testStringListSort() throws Exception {
        // number
        String [] strings = {"Hello", "China", "HangZhou"};
        List<String> list = Arrays.asList(strings);

        // 正序
        Collections.sort(list);
        System.out.println(list);

        // 根据字符串的长度正序
        Collections.sort(list, new Comparator<String>() {

            @Override
            public int compare(String o1, String o2) {
                int l1 = o1 == null? 0: o1.length();
                int l2 = o2 == null? 0: o2.length();
                return (l1 < l2)? -1: ((l1 == l2)?0:1);
            }
        });
        System.out.println(list);
    }
}

结果输出

// 正序
[1, 3, 5, 7, 11, 13, 14, 31]

// 逆序
[31, 14, 13, 11, 7, 5, 3, 1]

// 字符串正序,compareTo方法依次比较字符串中的每个字符
[China, HangZhou, Hello]

// 字符串长度正序
[China, Hello, HangZhou]

Map排序

构造单测样例,其中Map的Key和Value均为Integer类型。样例通过新建Comparator类,实现了Map根据Key的正序和逆序,根据Value的正序和逆序排列。示例如下:

    @Test
    public void testIntegerMapSort() throws Exception {
        // 构造HashMap
        Map<Integer, Integer> map = new HashMap<Integer, Integer>() {{
            put(1, 23);
            put(2, 20);
            put(3, 21);
        }};

        // 根据key正序
        List<Map.Entry<Integer, Integer>> entries = new ArrayList<>(map.entrySet());
        Collections.sort(entries, new Comparator<Map.Entry<Integer, Integer>>() {
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
                return o1.getKey().compareTo(o2.getKey());
            }
        });
        System.out.println(entries);

        // 根据key逆序
        Collections.sort(entries, new Comparator<Map.Entry<Integer, Integer>>() {
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
                return o2.getKey().compareTo(o1.getKey());
            }
        });
        System.out.println(entries);

        // 根据value正序
        Collections.sort(entries, new Comparator<Map.Entry<Integer, Integer>>() {
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
                return o1.getValue().compareTo(o2.getValue());
            }
        });
        System.out.println(entries);

        // 根据value逆序
        Collections.sort(entries, new Comparator<Map.Entry<Integer, Integer>>() {
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        System.out.println(entries);
    }

结果输出

// key正序
[1=23, 2=20, 3=21]

// key逆序
[3=21, 2=20, 1=23]

// value正序
[2=20, 3=21, 1=23]

// value逆序
[1=23, 3=21, 2=20]

自定义class排序

最后我们自定义class,implements Comparable接口,实现public int compareTo(T o)方法。自定义User如下:

package hello.core.sort;

/**
 * Created on 2018/8/16.
 *
 * @author eyangmeng@163.com
 */
public class User implements Comparable<User> {

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // User根据年龄大小排序
    @Override
    public int compareTo(User o) {
        return (this.age < o.age) ? -1 : ((this.age == o.age) ? 0 : 1);
    }

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

    private String name;
    private int age;
}

接下来我们构建单测样例实现自定义class的排序,实现了List和Map

    @Test
    public void testUserSort() throws Exception {

        // list User
        User marvin = new User("Marvin", 28);
        User james = new User("James", 33);
        User ai = new User("ai", 22);
        List<User> users = new ArrayList<>();
        users.add(marvin);
        users.add(james);
        users.add(ai);

        // User根据年龄正序排列
        Collections.sort(users);
        System.out.println(users);

        // map User: 依据value排序
        Map<Integer, User> map = new HashMap<Integer, User>() {{
            put(32, marvin);
            put(23, james);
            put(3, ai);
        }};
        List<Map.Entry<Integer, User>> entries = new ArrayList<>(map.entrySet());
        Collections.sort(entries, new Comparator<Map.Entry<Integer, User>>() {
            @Override
            public int compare(Map.Entry<Integer, User> o1, Map.Entry<Integer, User> o2) {
                return o1.getValue().compareTo(o2.getValue());
            }
        });
        System.out.println(entries);
    }

输出结果:

# List User: 年龄正序
[User{name='ai', age=22}, User{name='Marvin', age=28}, User{name='James', age=33}]

# Map User: Value-年龄正序
[3=User{name='ai', age=22}, 32=User{name='Marvin', age=28}, 23=User{name='James', age=33}]

参考文献

JDK Comparable<T>, Collections, Comparator<T>

### Java中对包含`Map`的`ArrayList`进行自定义排序Java中,如果要对包含`Map`对象的`ArrayList`进行自定义排序,可以通过实现`Comparator`接口并重写其`compare`方法来完成。以下是具体的方法说明: #### 方法概述 为了实现自定义排序,通常需要遵循以下逻辑: 1. 定义一个比较器(`Comparator`),该比较器会根据指定条件对`Map`中的特定键值进行比较。 2. 调用`Collections.sort()`方法,并传递待排序的列表以及上述比较器。 当处理`Map`类型的元素时,由于`Map`本身并不提供直接的顺序支持,因此需通过获取目标键对应的值来进行比较[^1]。 #### 示例代码 假设有一个`ArrayList<Map<String, String>>`,其中每个`Map`存储了一些键值对数据,现在希望按某个特定键(如"name")升序排列这些条目,则可采用如下方式实现: ```java import java.util.*; public class MapSortingExample { public static void main(String[] args) { List<Map<String, String>> list = new ArrayList<>(); // 添加一些示例数据到listMap<String, String> map1 = new HashMap<>(); map1.put("id", "3"); map1.put("name", "Charlie"); Map<String, String> map2 = new HashMap<>(); map2.put("id", "1"); map2.put("name", "Alice"); Map<String, String> map3 = new HashMap<>(); map3.put("id", "2"); map3.put("name", "Bob"); list.add(map1); list.add(map2); list.add(map3); System.out.println("Before Sorting:"); printList(list); Collections.sort(list, new Comparator<Map<String, String>>() { @Override public int compare(Map<String, String> o1, Map<String, String> o2) { return o1.get("name").compareTo(o2.get("name")); // 按照"name"字段排序 } }); System.out.println("\nAfter Sorting by Name:"); printList(list); } private static void printList(List<Map<String, String>> list){ for (Map<String, String> item : list){ System.out.println(item.toString()); } } } ``` 此程序首先创建了一个包含三个不同名字记录的列表,接着利用`Collections.sort()`函数对其进行名称字母顺序上的重新安排[^4]。 #### 关于泛型的应用 以上例子展示了如何运用带有泛型参数化的集合类——即`ArrayList<Map<String, String>>`—来保存复杂的数据结构,并且能够灵活地依据内部属性执行定制化排序操作[^2]。 另外值得注意的是,在实际开发过程中可能还会遇到更复杂的场景比如涉及多级嵌套的对象或者多种不同类型之间的相互转换等问题,此时就需要更加深入理解Java泛型机制及其边界限制等内容[^3]。 #### 排序注意事项 对于某些特殊情况下的排序需求,例如逆向排序或是基于数值大小而非字符串字典序等情况,则可以在编写比较器的时候调整相应的逻辑表达式[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值