TreeMap排序

TreeMap排序

TreeMap按照Key排序

TreeMap底层是根据红黑树的数据结构来构建的,默认是根据Key的自然排序来组织(比如Ingeger的大小,String的字典排序).所以,TreeMap只能只能按照key来排序,是不能根据Value来排序的.

key为基本包装类

当key属于基本包装类时(Integer,String等),它们都已经实现了Comparable接口,所以允许不重写compareTo()或者compare()方法.

public void defaultByKey() {
    Map<Integer, Character> map = new TreeMap<>();
    map.put(5, 'a');
    map.put(2, 'b');
    map.put(3, 'c');
    map.put(1, 'd');
    map.put(4, 'e');
    System.out.println(map);

    Map<String, Character> map2 = new TreeMap<>();
    map2.put("zzz", 'a');
    map2.put("ddd", 'b');
    map2.put("aaa", 'c');
    map2.put("ccc", 'd');
    map2.put("bbb", 'e');
    System.out.println(map2);
}

运行结果为:

{1=d, 2=b, 3=c, 4=e, 5=a}
{aaa=c, bbb=e, ccc=d, ddd=b, zzz=a}

key为自定义包装类

不实现自然排序或者定制排序

当key为自定义类时候,必须重写compareTo()或者compare()方法,否则报错.

class Person  {
    int age;

    public Person(int age) {
        this.age = age;
    }
}

public void comparableDemo() {
    Map<Person, String> map = new TreeMap<>();
    map.put(new Person(5), "wang");
    System.out.println(map);
}

运行结果为:

java.lang.ClassCastException: map.TreeMapDemo$Person cannot be cast to java.lang.Comparable

实现自然排序

自然排序即让被排序的类实现Comparable接口,然后重写compareTo方法.

class Person implements Comparable<Person> {
    int age;

    public Person(int age) {
        this.age = age;
    }

    @Override
    public int compareTo(Person o) {
        return this.age - o.age;
    }

    @Override
    public String toString() {
        return "Person{" +
            "age=" + age +
            '}';
    }
}

/**
 * 自然排序
 */
@Test
public void comparableDemo() {
    Map<Person, String> map = new TreeMap<>();
    map.put(new Person(5), "wang");
    map.put(new Person(2), "zhang");
    map.put(new Person(3), "liu");
    System.out.println(map);
}

运行结果为:

{Person{age=2}=zhang, Person{age=3}=liu, Person{age=5}=wang}

实现定制排序

定制排序即创建一个新的类并且实现Comparator接口,重写compare方法.创建TreeMap的时候,传入比较器.

class PersonD  {
    int age;

    public PersonD(int age) {
    this.age = age;
    }

    @Override
    public String toString() {
    return "PersonD{" +
    "age=" + age +
    '}';
    }
}

@Test
public void comparatorDemo() {
    Map<PersonD, String> map = new TreeMap<>(new Comparator<PersonD>() {
        @Override
        public int compare(PersonD o1, PersonD o2) {
            return o1.age - o2.age;
        }
    });
    map.put(new PersonD(5), "wang");
    map.put(new PersonD(2), "zhang");
    map.put(new PersonD(3), "liu");
    System.out.println(map);
}

按照Value排序

思路:将TreeMap的EntrySet转换成list(放入list中),然后使用Collections.sort排序.

/**
 * TreeMap按照value来排序
 */
public void sortByValue() {
    Map<Character, Integer> map = new TreeMap<>();
    map.put('q', 8);
    map.put('b', 8);
    map.put('a', 10);
    map.put('c', 3);
    map.put('d', 4);
    System.out.println("默认以Key排序: ");
    System.out.println(map);
    System.out.println("................................");

    List<Map.Entry<Character, Integer>> list = new ArrayList<>(map.entrySet());
    System.out.println("将entrySet放入list中: ");
    System.out.println(list);
    System.out.println("................................");


    // 匿名内部类方式重写compare方法
    //        Collections.sort(list, new Comparator<Map.Entry<Character, Integer>>() {
    //            @Override
    //            public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
    //                return o1.getValue().compareTo(o2.getValue());
    //            }
    //        });

    // lambda表达式重写compare方法
    Collections.sort(list, (o1, o2) -> {
        return o1.getValue().compareTo(o2.getValue());
    });

    System.out.println("按照value值排序后: ");
    System.out.println(list);
}

运行结果为:

默认以Key排序: 
{a=10, b=8, c=3, d=4, q=8}
................................
将entrySet放入list中: 
[a=10, b=8, c=3, d=4, q=8]
................................
按照value值排序后: 
[c=3, d=4, b=8, q=8, a=10]

上一篇:数据结构——符号表


下一篇:2021-11-05