目录
1、根据Key进行排序
Map的根据key排序需要用到TreeMap对象,因为它是默认按照升序进行输出的,可以使用比较器compareTo对它进行降序排序,Comparator可以对集合对象或者数组进行排序的比较器接口,实现该接口的public compare(T o1,To2)方法即可实现排序,该方法主要是根据第一个参数o1,小于、等于或者大于o2分别返回负整数、0或者正整数,若是按照升序可以直接省略比较器代码Map<String, String> treeMap = new TreeMap<String, String>();
return 0; // 只返回存储的第一个key的值,这里是{c=ddddd}
}
});
// Map<String, String> treeMap = new TreeMap<String, String>();
treeMap.put("c", "ccccc");
treeMap.put("a", "aaaaa");
treeMap.put("b", "bbbbb");
treeMap.put("d", "ddddd");
System.out.println(treeMap);
}
}
{a=aaaaa, b=bbbbb, c=ccccc, d=ddddd}
2、根据value值排序
利用List排序
对value排序我们就需要借助于Collections的sort(List<T> list, Comparator<? super T> c)方法,该方法根据指定比较器产生的顺序对指定列表进行排序。但是有一个前提条件,那就是所有的元素都必须能够根据所提供的比较器来进行比较。
这种方法通用于key和value排序,只需将比较器中o1.getValue().compareTo(o2.getValue())的getValue()改为getKey()即可。
public class MapTest
{
public static void main(String[] args) {
Map map = new HashMap();
map.put("设计与制作", "52");
map.put("创作表现", "15");
map.put("基本元素", "48");
map.put("艺术作品", "55");
//Set<Map.Entry<K, V>> entrySet();
List<Map.Entry<String,String>> list = new ArrayList<>(map.entrySet());
Collections.sort(list,new Comparator<Map.Entry<String,String>>(){
@Override
public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
Map<String,String> mapNew = new LinkedHashMap<>();
for (Map.Entry<String,String> entry:list){
mapNew.put(entry.getKey(),entry.getValue());
}
System.out.println(mapNew);
}
{创作表现=15, 基本元素=48, 设计与制作=52, 艺术作品=55}
3、根据value的长度排序
需求:存储一个key为Integer,value为String的map,根据String长度对map从小到大排序
结果:
3.1、用Pair配对
一开始用的是HashMap,但是后面发现HashMap是无序的,于是想把HashMap的一个键值对取出来,存到集合里,再对集合进行自定义排序,上网搜到有一个配对的类Pair,他有一个key和一个value属性,想到用来代替HashMap的一个键值对。
用ArrayList代替HashMap,然后ArrayList中的元素为配对类,变相实现了一个键对应一个值的集合,并且能够排序。
首先存储配对到集合中:
ArrayList<Pair<Integer, String>> pairs = new ArrayList<>();
Pair<Integer, String> pair;
pair = new Pair<>(1, "abc");
pairs.add(pair);
pair = new Pair<>(2, "abcd");
pairs.add(pair);
pair = new Pair<>(3, "ab");
pairs.add(pair);
pair = new Pair<>(4, "abcde");
pairs.add(pair);
对集合进行排序
调用ArrayList对象的sort方法进行排序,他需要Comparator接口,有三种实现方法:
内部类进行排序
public class Main {
public static void main(String[] args) {
ArrayList<Pair<Integer, String>> pairs = new ArrayList<>();
Pair<Integer, String> pair;
pair = new Pair<>(1, "abc");
pairs.add(pair);
pair = new Pair<>(2, "abcd");
pairs.add(pair);
pair = new Pair<>(3, "ab");
pairs.add(pair);
pair = new Pair<>(4, "abcde");
pairs.add(pair);
pairs.sort(new Main().new StringCmp());//建立Main内部类的一个实例对象
}
//实现比较接口的内部类
public class StringCmp implements Comparator{
@Override
public int compare(Object o1, Object o2) {
Pair<Integer, String> s1 = (Pair)o1;
Pair<Integer, String> s2 = (Pair)o2;
return new Integer(s1.getValue().length()).compareTo(s2.getValue().length());
}
}
}
匿名内部类进行排序
如果不需要复用这个排序的方法,单独为他写一个类太过浪费又不安全,可以使用匿名的内部类
public class Main {
public static void main(String[] args) {
ArrayList<Pair<Integer, String>> pairs = new ArrayList<>();
Pair<Integer, String> pair;
pair = new Pair<>(1, "abc");
pairs.add(pair);
pair = new Pair<>(2, "abcd");
pairs.add(pair);
pair = new Pair<>(3, "ab");
pairs.add(pair);
pair = new Pair<>(4, "abcde");
pairs.add(pair);
//使用匿名内部类
pairs.sort(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Pair<Integer, String> s1 = (Pair)o1;
Pair<Integer, String> s2 = (Pair)o2;
return new Integer(s1.getValue().length()).compareTo(s2.getValue().length());
}
});
}
}
lambda表达式
lambda表达式就是匿名内部类的简写版:
public class Main {
public static void main(String[] args) {
ArrayList<Pair<Integer, String>> pairs = new ArrayList<>();
Pair<Integer, String> pair;
pair = new Pair<>(1, "abc");
pairs.add(pair);
pair = new Pair<>(2, "abcd");
pairs.add(pair);
pair = new Pair<>(3, "ab");
pairs.add(pair);
pair = new Pair<>(4, "abcde");
pairs.add(pair);
pairs.sort((pair1, pair2)->{return new Integer(pair1.getValue().length()).compareTo(new Integer(pair2.getValue().length()));});
}
}
3.2、用TreeMap进行排序
Map有能够排序的实现类TreeMap,创建时传入Comparator的接口实现类,就能够实现存储是排序了:
public class MapTest{
public static void main(String[] args) {
TreeMap<String, Integer> treeMap = new TreeMap<String, Integer>((s1, s2)->{
return new Integer(s1.length()).compareTo(new Integer(s2.length()));
});
treeMap.put("aec",1);
treeMap.put("abcd",2);
treeMap.put("ab",3);
treeMap.put("abcde",4);
}
}
System.out.println(treeMap);//{ab=3, aec=1, abcd=2, abcde=4}
因为TreeMap只能按照key进行排序,而我的要求是根据value的长度进行排序,所有在这里我把key和value的类型互换了,但这样之前可以通过int类型的编号找到String类型值,在更改之后,就不能通过标号找到值了。虽然有好处良多,但是不符合我的情况。
3.3、HashMap转成list再排序
把HashMap转换为Set之后再转换成ArrayList再调用sort方法进行排序,达到根据value进行排序的效果:
public class Main {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(1, "aec");
hashMap.put(2, "abcd");
hashMap.put(3, "ab");
hashMap.put(4, "abcde");
ArrayList<Map.Entry<Integer, String>> arrayList = new ArrayList<>(hashMap.entrySet());
arrayList.sort((entry1, entry2)->{
return new Integer(entry1.getValue().length()).compareTo(new Integer(entry2.getValue().length()));
});
}
}
感觉这是第一种方法,加上一个HashMap得到的结果,这样可以从按照value进行排序(排序结果保存在arrayList中),也可以从key找到value(在HashMap中),但是存储内存却浪费了,多了一个list,不知道有没有直接根据value直接排序的map.
public class TestMapSort {
public static void main(String[] args) {
int i = new Integer(1).compareTo(3);
System.out.println(i);//-1
//Pair类在javafx.util 包中
List<Pair<Integer,String>> pairs = Lists.newArrayListWithExpectedSize(1);
Pair<Integer, String> pair;
pair = new Pair<>(1,"abc");
pairs.add(pair);
pair = new Pair<>(2, "abcd");
pairs.add(pair);
pair = new Pair<>(3, "ab");
pairs.add(pair);
pair = new Pair<>(4, "abcde");
pairs.add(pair);
pairs.sort(new Comparator<Pair<Integer, String>>() {
@Override
public int compare(Pair<Integer, String> o1, Pair<Integer, String> o2) {
if(o1.getValue().length() < o2.getValue().length()){
return -1;
}else return 1;
}
});
System.out.println(pairs);//[3=ab, 1=abc, 2=abcd, 4=abcde]
pairs.sort(new ComparePairs());
System.out.println(pairs);//[3=ab, 1=abc, 2=abcd, 4=abcde]
pairs.sort(
(p1,p2)->{
return new Integer(p1.getValue().length()).compareTo(p2.getValue().length());
});
System.out.println(pairs);//[3=ab, 1=abc, 2=abcd, 4=abcde]
pairs.sort(
(p1,p2)->{
return new Integer(p1.getValue().length()).compareTo(p2.getValue().length());
});
System.out.println(pairs);//[3=ab, 1=abc, 2=abcd, 4=abcde]
pairs.sort( Comparator.comparing(p -> new Integer(p.getValue().length())));
System.out.println(pairs);//[3=ab, 1=abc, 2=abcd, 4=abcde]
//只可以按照key排序
Map<String, Integer> treeMap = new TreeMap<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return new Integer(o1.length()).compareTo(o2.length());
}
});
treeMap.put("abc", 1);
treeMap.put("abcd", 2);
treeMap.put("ab", 3);
treeMap.put("abcde", 4);
System.out.println(treeMap);//{ab=3, abc=1, abcd=2, abcde=4}
Map<Integer, String> hashMap = new HashMap<>();
hashMap.put(1, "aec");
hashMap.put(2, "abcd");
hashMap.put(3, "ab");
hashMap.put(4, "abcde");
List<Map.Entry<Integer,String>> lists = new ArrayList<>(hashMap.entrySet());
lists.sort((entry1,entry2)->{
return new Integer(entry1.getValue().length()).compareTo(new Integer(entry2.getValue().length()));
});
System.out.println(lists);//[3=ab, 1=aec, 2=abcd, 4=abcde]
}
public static class ComparePairs implements Comparator{
@Override
public int compare(Object o1, Object o2) {
Pair<Integer,String> pair1 = (Pair) o1;
Pair<Integer,String> pair2 = (Pair) o2;
return new Integer(pair1.getValue().length()).compareTo(pair2.getValue().length());
}
}
}