java学习(3)Map的排序

1. 首先关于map排序分为java8之前的,和之后的。也分为按照key和按照value的。也分为按照默认排序和自己的排序器的,下面一一说明。

2. 一般排序按照key的话,一般key都是Integer和String,用TreeMap就可以了。

3. 首先上面已经说了,按照key排序的话,其实直接用TreeMap挺好的。

4. 首先是本次例子用的类(此类实现了Comparable接口。实际上下面有些事不需要实现的。因为有的是自己又另外加的选择器。我会指出来。)。这算是准备工作,为了能看懂下面的例子。

class Pet implements Comparable
{
	String name;
	int old;
	public Pet(String name, int old)
	{
		this.name = name;
		this.old = old;
	}
	public String toString()
	{
		return "name: "+name+",old: "+old;
		
	}
	
	@Override
	public int compareTo(Object o) {
		// TODO Auto-generated method stub
		return old-((Pet)o).old;
	}
}

然后是map的填充:

Pet p1 = new Pet("dog",2);
		Pet p2 = new Pet("cat",5);
		Pet p3 = new Pet("pig",3);
		Pet p4 = new Pet("wolf",1);
		Map<String, Pet> map = new HashMap<String,Pet>();
		//Map<String, Pet> map = new TreeMap<String,Pet>();
		map.put("d", p1);
		map.put("c", p2);
		map.put("p", p3);
		map.put("w", p4);

4. 首先是原来的一般做法,按照key排序:

4.1. 此处的Map是一定要知道类型的。是不能像前面遍历(另一篇文章)哪样为了追求普适性不用泛型。

4.2. 这里出现了Map.Entry类,可以看出来他是Map的内部类。因为原来Map的遍历用到iterator的时候还需要回到map把value取出来。但是现在用Entry不用了。更方便。Java8里面加了按照key和value排序,排序也更方便了。

4.3 思路很简单,就是把Map按照Map.Entry取出来,放到List里面,然后借助Collectins的sort进行排序。当然,此时需要自己在Pet类外部实现一个泛型是Map.Entry的Compator比较器。此时Pet是没必要实现Comparable的。也没有用。因为Pet自己实现属于按照Pet的内部排序,而此时需要的是Map.Entry。

4.4 当然,比较器类可以是外部类,也可以是内部类。个人倾向于内部类。因为那是专门针对每一个类的。一般就只会用一次。

//根据原来的java,Value
	public static Map compareByValue(Map map)
	{
		if(map==null||map.isEmpty())
			return null;
		ArrayList<Map.Entry<String, Pet>> list = new ArrayList<Map.Entry<String,Pet>>
		(map.entrySet());
		Collections.sort( list,new MapValueComparator());
		Map<String,Pet> returnMap = new LinkedHashMap<String,Pet>();
		for(Map.Entry<String, Pet> entry: list)
		{
			returnMap.put(entry.getKey(), entry.getValue());
			
		}
		
		return returnMap;
	}

//比较器类2
	 class MapValueComparator implements Comparator<Map.Entry<String, Pet>>{

		@Override
		public int compare(Entry<String, Pet> o1, Entry<String, Pet> o2) {
			// TODO Auto-generated method stub
			return o1.getValue().old-o2.getValue().old;
		}
		 
	 }

5. 按照key,原来的java方法:

5.1. 思路很简单,就是从Map里面取出来,放到TreeMap里面就行。如果可以,在一开始读入的时候就放到TreeMap里面也未尝不可。这里只是为了展示排序方法这么做。

5.2.TreeMap里面有个参数,就是排序器Compator,其实你不加这个参数,默认的是按照Key排序。前提是key本身是可排序的。

5.3. 这里的Comparator用的就是内部类。仅仅为了展示一下。

//根据原来的java,key
	public static Map compareByKey(Map map)
	{
		if(map==null||map.isEmpty())
		{
			return null;
		}
		//内部类的实现方式。
		Map<String,Pet> returnMap = new TreeMap<String,Pet>((new MapSort()).new MapKeyComparator());
		returnMap.putAll(map);
		return returnMap;
	}
//比较器类,只是用的是内部类。
class MapKeyComparator implements Comparator<String>{  
		    public int compare(String p1, String p2) {  
		        return p1.compareTo(p2);  
		    }
		 }

Java8中Map.Entry的新方法:

6. 按照key:

6.1. 这是看到一个外国大神的博客写的。感觉很厉害,排序和遍历都很厉害。用了很多原来没有用过的技巧。虽然代码很短。

6.2. 其实也很简单,就是map提取Entry的list之后转化成流(string()),然后把流排序按照传入的Comparator排序。而Map.Entry的静态方法里面ComparingByKey()等四个方法都是返回Comparator(记得当时看API的时候还纳闷为什么返回Comparator)。当然,这要求Value或者key可排序,如果不可,就自己定义Compartor传进去。这和上面其实并无二致,只是用的方式不一样。

6.3. 还有一点,就是其实上面的传入Comparator时也可以用这些静态方法。

6.4. 最后,关于Collectors,和Arrays,Collections差不多,可以自己看API.

//根据key:java新增comparingByKey()
		public static void sortByKey(Map map)
		{
			//System.out.println("sortByKey: ");
			List<Map.Entry<String, Pet>> compareByValue = (List<Entry<String, Pet>>) map
					.entrySet()
					.stream()
					.sorted(Map.Entry.comparingByKey())
					.collect(Collectors.toList());
			
			compareByValue.forEach(System.out::println);
			//System.out.println("sortByKey: end");
		}

7. 按照value:

//根据value:java新增comparingByValue()
	public static void sortByValue(Map map)
	{
		System.out.println("sortByValue: ");
		List<Map.Entry<String, Pet>> compareByValue = (List<Entry<String, Pet>>) map
				.entrySet()
				.stream()
				.sorted(Map.Entry.comparingByValue())
				.collect(Collectors.toList());
		
		compareByValue.forEach(System.out::println);	
		System.out.println("sortByValue: end");
	}

8. 传入参数的一个例子

8.1. 用的是Lamd表达式。

//根据key:java新增comparingByKey()
				public static void sortByKey2(Map map)
				{
					System.out.println("sortByKey2: ");
					List<Map.Entry<String, Pet>> compareByValue = (List<Entry<String, Pet>>) map
							.entrySet()
							.stream()
							.sorted(Map.Entry.comparingByValue((Pet p1,Pet p2)->{
								return p1.name.length()-p2.name.length();
							}))
							.collect(Collectors.toList());// java.lang.String cannot be cast to com.map.Pet
					
					compareByValue.forEach(System.out::println);
					System.out.println("sortByKey2: end");
				}
    原文作者:kaikai7654321
    原文地址: https://blog.csdn.net/kaka0930/article/details/52996486
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞