map key value的排序问题
2016-04-10 05:02
519 查看
一、简单描述
Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,HashTable以及LinkedHashMap等。
TreeMap:能够把它保存的记录根据键(key)排序,默认是按升序排序,也可以指定排序的比较器,该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的
Comparator 进行排序,具体取决于使用的构造方法。
HashMap的值是没有顺序的,它是按照key的HashCode来实现的,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null(多条会覆盖);允许多条记录的值为
Null。非同步的。
Map.Entry返回Collections视图。
注:map简单的UML
二、排序的具体实现
(1)较简单的排序方式(直接根据key值进行比较),按key值排序
TreeMap 接收的comparator的接口默认是key值的排序,源代码如下:
(2) 根据Map.Entry进行排序,即可实现key值的排序,也可以实现value值的排序
注:java8 在Map接口中的Entry接口中实现了根据key、value排序的接口,源代码如下:
(3)当要比较的key或者value 是一个对象的时候,你可以定义一个comparator进行排序,java8 在Map接口中的Entry接口有两个接收comparator的方法,源码如下:
结束语:这是学习源代码时个人的见解,如有不对的地方,请指正,不尽感激
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); }
结束语:这是学习源代码时个人的见解,如有不对的地方,请指正,不尽感激
相关文章推荐
- [091127]Dark Blue幽深之蓝【汉化硬盘版】[带全CG存档&攻略+日文原版文件]
- OS开发UI篇—UITabBarController简单介绍
- UI测试
- js模块化之require.js
- UI调试神器 for ios:Reveal的使用与破解
- invalid bundle ipad multitasking support requires launch story board in bundle ...
- required opengl extension,please update your opengl driver
- 用UIButton的类方法ButtonWithType创建时调用的是initWithFrame方法
- 轻量级应用开发之(08)UITableView
- 特殊权限
- druid 数据库密码加密
- 在Android value中添加颜色resource文件
- [BZOJ4430][Nwerc2015]Guessing Camels赌骆驼
- STL学习系列七:优先级队列priority_queue容器
- easyui的datagrid删除一条记录后更新出问题
- 梦想中的图文发布——UEditor使用
- UITableView进阶注意点
- pop push UIViewController 手势过渡动画
- easyui跨iframe属性datagrid
- iOS——Segue的使用