背景

开发过程中,往往需要对结果集进行排序显示,对list来说,相对简单。但很多人习惯了list的排序方式,在对待map类型的排序时,往往使用HashMap存储,然后利用list对键值进行排序。其实这是对数据结果的误解!HashMap不支持排序即不存储排序结果,但TreeMap可以直接排序,使用它可以明显提升开发效率和减少代码工作量。LinkedHashMap 是HashMap的一个子类,保存了记录的插入顺序,数据库可以排序的数据尽量在数据库完成,返回map使用LinkedHashMap保存。

List排序实例

基本类型使用Collections.sort(List<T> list);

示例代码:

	public static void main(String[] args) {
		List<String> unsorted=new ArrayList<>();
		unsorted.add("aaaaaa");
		unsorted.add("cccccc");
		unsorted.add("dddd");
		unsorted.add("bbbbb");
		Collections.sort(unsorted);
for(String s:unsorted) {
			System.out.println(s);
		}
	}

运行结果:

aaaaaa
bbbbb
cccccc
dddd

如果想要逆序,使用Collections.reverse(unsorted)方法即可:

	public static void main(String[] args) {
		List<String> unsorted=new ArrayList<>();
		unsorted.add("aaaaaa");
		unsorted.add("cccccc");
		unsorted.add("dddd");
		unsorted.add("bbbbb");
		Collections.sort(unsorted);
		Collections.reverse(unsorted);
for(String s:unsorted) {
			System.out.println(s);
		}
	}

运行结果:

dddd
cccccc
bbbbb
aaaaaa

引用类型使用

Collections.sort(List<T> list, Comparator<? super T> c)或者使用Comparator.comparing 进行排序,实例如下:

添加一个要排序的pojo:

public class UserInfo implements Serializable {
private static final long serialVersionUID = 1L;
private String userName;
private Date birthday;
private int age;
private boolean female;
//getter setter
public static UserInfo create(String userName,Date birthday,int age,boolean female) {
		UserInfo userinfo= new UserInfo();
		userinfo.setUserName(userName);
		userinfo.setBirthday(birthday);
		userinfo.setAge(age);
		userinfo.setFemale(female);
return userinfo;
	}
@Override
public String toString() {
		System.out.println("userName="+this.getUserName()+",birthDay="+this.getBirthday().toGMTString()+",age="+this.getAge()+",female="+this.isFemale());
return "";
	}
}

测试实例

	private static void referenceTypeSortTest() {
		Calendar cal=Calendar.getInstance();
		cal.set(1990, 1, 1);
		List<UserInfo> unsorted=new ArrayList<>();
		unsorted.add(UserInfo.create("aaaa", cal.getTime(), 31, false));

		Calendar cal1=Calendar.getInstance();
		cal1.set(2000, 1, 1);
		unsorted.add(UserInfo.create("cccccc", cal1.getTime(), 21, true));

		Calendar cal2=Calendar.getInstance();
		cal2.set(2010, 1, 1);
		unsorted.add(UserInfo.create("dddd", cal2.getTime(), 11, false));

		Calendar cal3=Calendar.getInstance();
		cal2.set(2020, 1, 1);
		unsorted.add(UserInfo.create("bbbbb", cal2.getTime(), 1, true));		
		unsorted.sort(Comparator.comparingLong(e -> e.getBirthday().getTime()));
for(UserInfo s:unsorted) {
			System.out.println(s.toString());
		}

	}

返回结果

userName=aaaa,birthDay=1 Feb 1990 02:21:36 GMT,age=31,female=false

userName=cccccc,birthDay=1 Feb 2000 02:21:36 GMT,age=21,female=true

userName=dddd,birthDay=1 Feb 2010 02:21:36 GMT,age=11,female=false

userName=bbbbb,birthDay=1 Feb 2020 02:21:36 GMT,age=1,female=true

jdk8 Stream方式stream().sorted()

与上例类似,改造如下:

unsorted.stream().sorted(Comparator.comparingLong(e -> e.getBirthday().getTime()));
TreeMap键排序实例

基础类型的TreeMap按照键排序,默认升序,实例:

	private static void mapBaseTypeSortTest() {
        TreeMap<Integer,String> map1 = new TreeMap<Integer,String>();  //默认的TreeMap升序排列
        TreeMap<Integer,String> map2= new TreeMap<Integer,String>(new Comparator<Integer>(){
public int compare(Integer a,Integer b){
return b-a;            
            }
            });
        map1.put(1,"aaaaa");
        map1.put(2,"bbbbb");
        map1.put(7, "cccccc");
        map1.put(5,"dddddd");
        System.out.println("map1="+map1);

        map2.put(1,"aaaaa");
        map2.put(2,"bbbbb");
        map2.put(7, "cccccc");
        map2.put(5,"dddddd");
        System.out.println("Map2="+map2);  
	}

运行结果如下:

map1={1=aaaaa, 2=bbbbb, 5=dddddd, 7=cccccc}
Map2={7=cccccc, 5=dddddd, 2=bbbbb, 1=aaaaa}
TreeMap值排序实例

推荐使用LinkedHashMap

	private static void valueMapBaseTypeSortTest() {
		LinkedHashMap<Integer,String> map1 = new LinkedHashMap<Integer,String>(); 

        map1.put(1,"aaaaa");
        map1.put(2,"bbbbb");
        map1.put(7, "cccccc");
        map1.put(5,"dddddd");
        System.out.println("map1="+map1);

	}	
小结
  • HashTable底层是哈希数据表结构,不可以使用Null作为键或者值;该集合线程是同步的;

  • HashMap底层是哈希数据表结构,可以使用Null作为键或者值,该集合线程是不同步的;

  • TreeMap底层是二叉树结构,线程不同步,可以对Map中的键值可以排序.

  • LinkedHashMap 是HashMap的一个子类,保存了记录的插入顺序;