1.Map的排序问题
在此我们使用TreeMap来做示例,创建TreeMap使用的是sortedMapOf()来创建。
(1)TreeMap默认以key来升序
var map1 = sortedMapOf<String, Int>()
map1.put("Java", 30)
map1.put("Android", 60)
map1.put("C++", 50)
map1.put("Kotlin", 80)
map1["C"] = 70
println(map1)
{Android=60, C=70, C++=50, Java=30, Kotlin=80}
(2)以key值来降序
var comparator = kotlin.Comparator { key1: String, key2: String -> key2.compareTo(key1) }
var map2 = TreeMap<String, Int>(comparator)
map2.put("Java", 30)
map2.put("Android", 60)
map2.put("C++", 50)
map2.put("Kotlin", 80)
map2["C"] = 70
println(map2)
{Kotlin=80, Java=30, C++=50, C=70, Android=60}
(3)以value值来排序
var map3 = TreeMap<String, Int>()
map3.put("Java", 30)
map3.put("Android", 60)
map3.put("C++", 50)
map3.put("Kotlin", 80)
map3["C"] = 70
//升序
val mapSort = map3.entries.sortedBy { it.value }
.associateBy({ it.key }, { it.value })
println(mapSort)
//倒序
val mapDescSort = map3.entries.sortedByDescending { it.value }
.associateBy({ it.key }, { it.value })
println(mapDescSort)
//升序
val toMap = map3.toList().sortedBy { it.second }.toMap()
println(toMap)
{Java=30, C++=50, Android=60, C=70, Kotlin=80}
{Kotlin=80, C=70, Android=60, C++=50, Java=30}
{Java=30, C++=50, Android=60, C=70, Kotlin=80}
(4)List转成Map的形式
在开发中,经常用到把一个List按一定规则转换为Map来使用。下面介绍下几种常用的转换方式。
data class User(val id: Long, val name: String, val age: Int)
fun main(args: Array<String>) {
val users = listOf(User(1, "张三", 20), User(2, "李四", 20), User(3, "王五", 25), User(4, "赵六", 25))
// 变为以id为key, user为value的map,类型为Map<Long, User>
println(users.associateBy { it.id })
// 变为以id为key,name为value的map,类型为Map<Long, String>
println(users.associate { it.id to it.name })
// 可以自定义key和value的map,类型为Map<String, String>
println(users.associateBy({ "id:${it.id}" }, { "name:${it.name}" }))
// 生成按age聚合,对象List为value的map,类型为Map<Int, List<User>>
println(users.groupBy { it.age })
}
{1=User(id=1, name=张三, age=20), 2=User(id=2, name=李四, age=20), 3=User(id=3, name=王五, age=25), 4=User(id=4, name=赵六, age=25)}
{1=张三, 2=李四, 3=王五, 4=赵六}
{id:1=name:张三, id:2=name:李四, id:3=name:王五, id:4=name:赵六}
{20=[User(id=1, name=张三, age=20), User(id=2, name=李四, age=20)], 25=[User(id=3, name=王五, age=25), User(id=4, name=赵六, age=25)]}
转成的Map其实都是LinkedHashMap,看输出的结果也可以看出来,生成的Map中的对象顺序和List中的一致。
当key的重复的时候,后面的值覆盖前面的值。比如添加一行代码:
println(users.associateBy { it.age })
{20=User(id=2, name=李四, age=20), 25=User(id=4, name=赵六, age=25)}
(5)Java中Map的排序方式
TreeMap默认是升序的,如果我们需要改变排序方式,则需要使用比较器:Comparator。
Comparator可以对集合对象或者数组进行排序的比较器接口,实现该接口的public compare(T o1,To2)方法即可实现排序,该方法主要是根据第一个参数o1,小于、等于或者大于o2分别返回负整数、0或者正整数。
//TreeMap按照Key进行降序排列
public class TreeMapTest {
public static void main(String[] args) {
Map<String, String> map = new TreeMap<String, String>(
new Comparator<String>() {
public int compare(String obj1, String obj2) {
// 降序排序
return obj2.compareTo(obj1);
}
});
map.put("c", "ccccc");
map.put("a", "aaaaa");
map.put("b", "bbbbb");
map.put("d", "ddddd");
Set<String> keySet = map.keySet();
Iterator<String> iter = keySet.iterator();
while (iter.hasNext()) {
String key = iter.next();
System.out.println(key + ":" + map.get(key));
}
}
}
d:ddddd
c:ccccc
b:bbbbb
a:aaaaa
根据TreeMap的value来进行排序,对value排序我们就需要借助于Collections的sort(List list, Comparator<? super T> c)方法,该方法根据指定比较器产生的顺序对指定列表进行排序。但是有一个前提条件,那就是所有的元素都必须能够根据所提供的比较器来进行比较。
public class TreeMapTest {
//TreeMap按照value来进行排序
public static void main(String[] args) {
Map<String, String> map = new TreeMap<String, String>();
map.put("d", "ddddd");
map.put("b", "bbbbb");
map.put("a", "aaaaa");
map.put("c", "ccccc");
//这里将map.entrySet()转换成list
List<Map.Entry<String,String>> list = new ArrayList<Map.Entry<String,String>>(map.entrySet());
//然后通过比较器来实现排序
Collections.sort(list,new Comparator<Map.Entry<String,String>>() {
//升序排序
public int compare(Entry<String, String> o1,
Entry<String, String> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
for(Map.Entry<String,String> mapping:list){
System.out.println(mapping.getKey()+":"+mapping.getValue());
}
}
}
a:aaaaa
b:bbbbb
c:ccccc
d:ddddd
我们都知道HashMap的值是没有顺序的,它是按照key的HashCode来实现的。对于这种无序的HashMap我们要怎么来实现排序呢?参照TreeMap的value排序,我们一样的也可以实现HashMap的排序。
//HashMap按照value进行排序
public class HashMapTest {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("c", "ccccc");
map.put("a", "aaaaa");
map.put("b", "bbbbb");
map.put("d", "ddddd");
List<Map.Entry<String,String>> list = new ArrayList<Map.Entry<String,String>>(map.entrySet());
Collections.sort(list,new Comparator<Map.Entry<String,String>>() {
//升序排序
public int compare(Entry<String, String> o1,
Entry<String, String> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
for(Map.Entry<String,String> mapping:list){
System.out.println(mapping.getKey()+":"+mapping.getValue());
}
}
}
a:aaaaa
b:bbbbb
c:ccccc
d:ddddd