map key value的排序问题

  一、简单描述

Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,HashTable以及LinkedHashMap等。

        TreeMap:能够把它保存的记录根据键(key)排序,默认是按升序排序,也可以指定排序的比较器该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。

        HashMap的值是没有顺序的,它是按照key的HashCode来实现的,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null(多条会覆盖);允许多条记录的值为 Null。非同步的。

        Map.Entry返回Collections视图。

        注:map简单的UML

二、排序的具体实现

(1)较简单的排序方式(直接根据key值进行比较),按key值排序

 Map<String, String> map = new TreeMap<String, String>(new
		 Comparator<String>() {
		 public int compare(String obj1, String obj2) {
		 return obj1.compareTo(obj2);
		 }
		 });
		 map.put("b", "1111");
		 map.put("d", "2222");
		 map.put("c", "3333");
		 map.put("a", "4444");
		
		 for (Entry entry : map.entrySet()) {
		 System.err.println(entry.getKey() + "========" + entry.getValue());
		 }





TreeMap 接收的comparator的接口默认是key值的排序,源代码如下:

/**
     * Constructs a new, empty tree map, ordered according to the given
     * comparator.  All keys inserted into the map must be <em>mutually
     * comparable</em> by the given comparator: {@code comparator.compare(k1,
     * k2)} must not throw a {@code ClassCastException} for any keys
     * {@code k1} and {@code k2} in the map.  If the user attempts to put
     * a key into the map that violates this constraint, the {@code put(Object
     * key, Object value)} call will throw a
     * {@code ClassCastException}.
     *
     * @param comparator the comparator that will be used to order this map.
     *        If {@code null}, the {@linkplain Comparable natural
     *        ordering} of the keys will be used.
     */
    public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }



 
(2) 根据Map.Entry进行排序,即可实现key值的排序,也可以实现value值的排序 

Map<String, String> map = new HashMap();
		map.put("1", "b");
		map.put("2", "a");
		map.put("4", "e");
		map.put("5", "c");
		map.put("3", "d");
		Set<Map.Entry<String, String>> keyEntries = new TreeSet<Map.Entry<String, String>>(
				(Comparator<Map.Entry<String, String>>) (c1, c2) -> c1.getKey().compareTo(c2.getKey()));
		keyEntries.addAll(map.entrySet());
		for (Entry<String, String> entry : keyEntries) {
			System.err.println(entry.getKey() + "----" + entry.getValue());
		}


		Set<Map.Entry<String, String>> valueEntries = new TreeSet<Map.Entry<String, String>>(
				(Comparator<Map.Entry<String, String>>) (c1, c2) -> c1.getValue().compareTo(c2.getValue()));
		valueEntries.addAll(map.entrySet());
		for (Entry<String, String> entry : valueEntries) {
			System.err.println(entry.getKey() + "----" + entry.getValue());
		}




注:java8 在Map接口中的Entry接口中实现了根据key、value排序的接口,源代码如下:

 public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> c1.getKey().compareTo(c2.getKey());
        }
   public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> c1.getValue().compareTo(c2.getValue());
        }



(3) 当要比较的key或者value 是一个对象的时候,你可以定义一个comparator进行排序java8 在Map接口中的Entry接口有两个接收comparator的方法,源码如下:

 public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
            Objects.requireNonNull(cmp);
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
        }
    public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
            Objects.requireNonNull(cmp);
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
        }
    }
例子:

Map<String, Person> personMap = new HashMap<String, Person>();
		personMap.put("a", new Person(1, "aaa"));
		personMap.put("acd", new Person(4, "acd"));
		personMap.put("abc", new Person(3, "abc"));
		personMap.put("eda", new Person(2, "eda"));
		Set<Map.Entry<String, Person>> valueEntries = new TreeSet(Map.Entry.comparingByValue(new Comparator<Person>() {
			@Override
			public int compare(Person p1, Person p2) {
				return p1.id - p2.id;
			}
		}));
		// Set<Map.Entry<String, Person>> valueEntries = new
		// TreeSet<Map.Entry<String, Person>>(
		// new Comparator<Map.Entry<String, Person>>() {
		//
		// @Override
		// public int compare(Entry<String, Person> o1, Entry<String, Person>
		// o2) {
		// Person p1 = o1.getValue();
		// Person p2 = o2.getValue();
		// return p1.id - p2.id;
		// }
		// });
		valueEntries.addAll(personMap.entrySet());
		for (Entry<String, Person> entry : valueEntries) {
			System.err.println(entry.getKey() + "----" + entry.getValue().id);
		}


 

结束语:这是学习源代码时个人的见解,如有不对的地方,请指正,不尽感激


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值