Discussion on sorting problem in java Collection

  • 2020-05-19 04:56:03
  • OfStack

Here we discuss sorting by list, set, and map, including sorting by value of map.

1) list sorting

list sorting can be done either directly using Collections's sort method, or Arrays's sort method, which, after all, is Collections calling Arrays's sort method.


public static <T> void sort(List<T> list, Comparator<? super T> c) { 
  Object[] a = list.toArray(); 
  Arrays.sort(a, (Comparator)c); 
  ListIterator i = list.listIterator(); 
  for (int j=0; j<a.length; j++) { 
    i.next(); 
    i.set(a[j]); 
  } 
  } 

If it is a custom object, we need to implement the Comparable interface so that the object itself has the ability to "compare", of course, we can also use Comparator externally to specify its ordering.

Such as:


package com.fox; 
 
/** 
 * @author huangfox 
 * @desc 
 */
public class User implements Comparable<User> { 
 
  private String name; 
  private int age; 
 
  public User() { 
  } 
 
  public User(String name, int age) { 
    super(); 
    this.name = name; 
    this.age = age; 
  } 
 
  @Override
  public String toString() { 
    return "name:" + name + ",age:" + age; 
  } 
 
  public String getName() { 
    return name; 
  } 
 
  public void setName(String name) { 
    this.name = name; 
  } 
 
  public int getAge() { 
    return age; 
  } 
 
  public void setAge(int age) { 
    this.age = age; 
  } 
 
  @Override
  public int compareTo(User o) { 
    if (o.age < this.age) 
      return 1; 
    else if (o.age > this.age) 
      return -1; 
    else
      return 0; 
  } 
 
  /** 
   * @param args 
   */
  public static void main(String[] args) { 
    User u1 = new User("fox", 11); 
    User u2 = new User("fox2", 21); 
    System.out.println(u2.compareTo(u1)); 
  } 
 
}

Sorting:


// List<User> us = new ArrayList<User>(); 
    List<User> us = new LinkedList<User>(); 
    us.add(new User("f5", 12)); 
    us.add(new User("f2", 22)); 
    us.add(new User("f3", 2)); 
    us.add(new User("f4", 14)); 
    us.add(new User("f5", 32)); 
    us.add(new User("f4", 12)); 
    us.add(new User("f7", 17)); 
    us.add(new User("f8", 52)); 
    System.out.println(us.toString()); 
    long bt = System.nanoTime(); 
    Collections.sort(us, new Comparator<User>() { 
 
      @Override
      public int compare(User o1, User o2) { 
        if (o1.getAge() < o2.getAge()) 
          return -1; 
        else if (o1.getAge() > o2.getAge()) 
          return 1; 
        else
          return o1.getName().compareTo(o2.getName()); 
      } 
    }); 
    long et = System.nanoTime(); 
    System.out.println(et - bt); 
    System.out.println(us.toString());

Of course, Collections.sort (us) can be used directly here. Here, Comparator does a little bit of optimization on compareTo, User's own comparison method (ranking people of the same age by user name, String's ranking).

Simply mentioned 1, the sorting of Arrays adopts insertion sort and merge sort, and when the array length is small, directly insert sort.

2) set sorting

set includes HashSet and TreeSet, HashSet is based on HashMap, and TreeSet is based on TreeMap.

TreeMap is implemented with red-black tree, and it has sorting function naturally. "sorting function naturally" means it has iterators of ascending and descending order.

So how do you rank HashSet? We can convert HashSet to List, and then sort by List.

Such as:


Set<User> us = new HashSet<User>(); 
    // Set<User> us = new TreeSet<User>(); 
    // Set<User> us = new TreeSet<User>(new Comparator<User>() { 
    // 
    // @Override 
    // public int compare(User o1, User o2) { 
    // if (o1.getAge() < o2.getAge()) 
    // return -1; 
    // else if (o1.getAge() > o2.getAge()) 
    // return 1; 
    // else 
    // return o1.getName().compareTo(o2.getName()); 
    // } 
    // }); 
    us.add(new User("f5", 12)); 
    us.add(new User("f2", 22)); 
    us.add(new User("f3", 2)); 
    us.add(new User("f4", 14)); 
    us.add(new User("f5", 32)); 
    us.add(new User("f4", 12)); 
    us.add(new User("f7", 17)); 
    us.add(new User("f8", 52)); 
    // set -> array 
    List<User> list = new ArrayList<User>(us); 
    System.out.println(list); 
    Collections.sort(list); 
    System.out.println(list);

You can also convert HashSet to an array sorted by Arrays.

3) map sorting

map includes HashMap and TreeMap. As mentioned above, TreeMap is implemented with red-black tree, which naturally has sorting function.

So how does HashMap sort by "key"? The method is very simple, using HashMap to construct an TreeMap.


Map<String, Integer> us = new HashMap<String, Integer>(); 
    // Map<String, Integer> us = new TreeMap<String, Integer>(); 
    us.put("f1", 12); 
    us.put("f2", 13); 
    us.put("f5", 22); 
    us.put("f4", 42); 
    us.put("f3", 15); 
    us.put("f8", 21); 
    us.put("f6", 123); 
    us.put("f7", 1); 
    us.put("f9", 19); 
    System.out.println(us.toString()); 
    System.out.println(new TreeMap<String, Integer>(us));

How to sort by "value"?


//  In accordance with the value The sorting  
    Set<Entry<String, Integer>> ks = us.entrySet(); 
    List<Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>( 
        ks); 
    Collections.sort(list, new Comparator<Entry<String, Integer>>() { 
 
      @Override
      public int compare(Entry<String, Integer> o1, 
          Entry<String, Integer> o2) { 
        if (o1.getValue() < o2.getValue()) 
          return -1; 
        else if (o1.getValue() > o2.getValue()) 
          return 1; 
        return 0; 
      } 
    }); 
    System.out.println(list);

The Entry of map is proposed into the set structure, then set is transformed into list, and finally, list is sorted.


Related articles: