java 遍历map 排序map的key和value

时间:2022-10-26 10:50:56

经典的排序map,要复习啊:

package com.citi;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestSortMap2 {
	private final static Logger logger = LoggerFactory.getLogger(TestSortMap2.class);
	public static void main(String... abc){
		Map<Integer, String> map = new HashMap<Integer, String>();
		map.put(1, "a");
		map.put(2, "b");
		map.put(3, "c");
		for(Integer integer : map.keySet()){
			logger.info("key= " + integer + "  and  value= " + map.get(integer));
		}
		Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator(); 
		while(it.hasNext()){
			Map.Entry<Integer, String> entry = it.next();
			logger.info("key= " + entry.getKey() + "  and  value= " + entry.getValue());
		}
		for (Map.Entry<Integer, String> entry : map.entrySet()) {  
			logger.info("key= " + entry.getKey() + "  and  value= "  
                    + entry.getValue());  
        } 
		for(String string :map.values()){
			logger.info("value is "+string);  
		}
	}
}

第三种常用,第一种遍历其实遍历了两次map,Sonar检查会给critical issue.

TreeSet默认是升序排列,可以做降序排列:

package com.citi;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestSortSet {
	final static Logger logger = LoggerFactory.getLogger(TestSortSet.class);
	public static void main(String... abc){
		Set<Integer> set = new TreeSet<Integer>(new Comparator<Integer>(){
			@Override
			public int compare(Integer o1, Integer o2) {
				return o2.compareTo(o1);
			}
		});
		set.add(2);
		set.add(1);
		set.add(12);
		set.add(4);
		int count=0;
		for(Integer in : set){
			count++;
			logger.info(count+" times "+"the value is {}",String.valueOf(in));
		}
	}
}

输出:

<span style="font-size:18px;">SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Documents%20and%20Settings/Administrator/%e6%a1%8c%e9%9d%a2/%e6%96%b0%e5%bb%ba%e6%96%87%e4%bb%b6%e5%a4%b9%20(4)/slf4j-1.7.7/slf4j-log4j12-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Documents%20and%20Settings/Administrator/%e6%a1%8c%e9%9d%a2/%e6%96%b0%e5%bb%ba%e6%96%87%e4%bb%b6%e5%a4%b9%20(4)/slf4j-1.7.7/slf4j-jdk14-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
1 times the value is 12
  2 times the value is 4
  3 times the value is 2
  4 times the value is 1</span>

Student类:

package com.citi;

import java.util.Date;

public class Student {
	private int id;
	private String name;
	private Date birthDay;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Student(int id, String name, Date birthDay) {
		super();
		this.id = id;
		this.name = name;
		this.birthDay = birthDay;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Date getBirthDay() {
		return birthDay;
	}
	public void setBirthDay(Date birthDay) {
		this.birthDay = birthDay;
	}
}

现在对一批学生进行排序:按id升序排列,id相同则按name排序,id和name都相同,则按birthDay排序:

第一种方式,做个匿名的Comparator内部类实现:


package com.citi;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestSortMap {
	final static Logger logger = LoggerFactory.getLogger(TestSortMap.class);
	public static void main(String... args) throws Exception{
		final ThreadLocal<DateFormat> DF = new ThreadLocal<DateFormat>() {  
	        protected DateFormat initialValue() {    
	           return new SimpleDateFormat("yyyy-MM-dd");    
	          }    
	    }; 
		Student s1 = new Student(2,"mucy",DF.get().parse("2014-10-01"));
		Student s2 = new Student(2,"lucy",DF.get().parse("2014-10-03"));
		Student s3 = new Student(10,"maomi",DF.get().parse("2014-10-05"));
		Student s4 = new Student(34,"jack",DF.get().parse("2014-10-14"));
		Student s5 = new Student(13,"tom",DF.get().parse("2014-10-04"));
		Student s6 = new Student(2,"lucy",DF.get().parse("2014-10-02"));
		Map<Integer,Student> stu = new HashMap<Integer,Student>();
		stu.put(2, s1);
		stu.put(1, s2);
		stu.put(10, s3);
		stu.put(4, s4);
		stu.put(7, s5);
		stu.put(8, s6);
		List<Map.Entry<Integer,Student>> list = new ArrayList<Map.Entry<Integer,Student>>(stu.entrySet());
		Collections.sort(list, new Comparator<Map.Entry<Integer,Student>>(){
			@Override
			public int compare(Entry<Integer, Student> o1,
					Entry<Integer, Student> o2) {
				if(o1.getValue().getId()-o2.getValue().getId()==0){
					if(o1.getValue().getName().compareTo(o2.getValue().getName())==0){
						return o1.getValue().getBirthDay().compareTo(o2.getValue().getBirthDay());
					}
					return o1.getValue().getName().compareTo(o2.getValue().getName());
				}
				return o1.getValue().getId()-o2.getValue().getId();
			}
		});
		for(Map.Entry<Integer,Student> entry:list){
			logger.info(entry.getValue().getId()+"-"+entry.getValue().getName()+"-"+DF.get().format(entry.getValue().getBirthDay()));
		}
	}
}

输出:

<span style="font-size:18px;">SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Documents%20and%20Settings/Administrator/%e6%a1%8c%e9%9d%a2/%e6%96%b0%e5%bb%ba%e6%96%87%e4%bb%b6%e5%a4%b9%20(4)/slf4j-1.7.7/slf4j-log4j12-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Documents%20and%20Settings/Administrator/%e6%a1%8c%e9%9d%a2/%e6%96%b0%e5%bb%ba%e6%96%87%e4%bb%b6%e5%a4%b9%20(4)/slf4j-1.7.7/slf4j-jdk14-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
2-lucy-2014-10-02
  2-lucy-2014-10-03
  2-mucy-2014-10-01
  10-maomi-2014-10-05
  13-tom-2014-10-04
  34-jack-2014-10-14</span>

第二种方式,让Student实现Comparable接口,重写Student类,用TreeSet举例:

package com.citi;

import java.util.Date;

public class Student implements java.lang.Comparable<Student>{
	private int id;
	private String name;
	private Date birthDay;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Student(int id, String name, Date birthDay) {
		this.id = id;
		this.name = name;
		this.birthDay = birthDay;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Date getBirthDay() {
		return birthDay;
	}
	public void setBirthDay(Date birthDay) {
		this.birthDay = birthDay;
	}
	@Override
	public int compareTo(Student o) {
		if(this.getId()-o.getId()==0){
			if(this.getName().compareTo(o.getName())==0){
				return this.getBirthDay().compareTo(o.getBirthDay());
			}
			return this.getName().compareTo(o.getName());
		}
		return this.getId()-o.getId();
	}
}

测试类:

package com.citi;

import java.util.Set;
import java.util.TreeSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestSortSet2{
	final static Logger logger = LoggerFactory.getLogger(TestSortSet2.class);
	public static void main(String... args) throws Exception{
		
		Student s1 = new Student(2,"mucy",Constants.DF.get().parse("2014-10-01"));
		Student s2 = new Student(2,"lucy",Constants.DF.get().parse("2014-10-03"));
		Student s3 = new Student(10,"maomi",Constants.DF.get().parse("2014-10-05"));
		Student s4 = new Student(34,"jack",Constants.DF.get().parse("2014-10-14"));
		Student s5 = new Student(13,"tom",Constants.DF.get().parse("2014-10-04"));
		Student s6 = new Student(2,"lucy",Constants.DF.get().parse("2014-10-02"));
		Set<Student> set = new TreeSet<Student>();
		set.add(s1);
		set.add(s2);
		set.add(s3);
		set.add(s4);
		set.add(s5);
		set.add(s6);
		for(Student student :set){
			logger.info(student.getId()+"-"+student.getName()+"-"+Constants.DF.get().format(student.getBirthDay()));
		}
	}
}

输出:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Documents%20and%20Settings/Administrator/%e6%a1%8c%e9%9d%a2/%e6%96%b0%e5%bb%ba%e6%96%87%e4%bb%b6%e5%a4%b9%20(4)/slf4j-1.7.7/slf4j-log4j12-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Documents%20and%20Settings/Administrator/%e6%a1%8c%e9%9d%a2/%e6%96%b0%e5%bb%ba%e6%96%87%e4%bb%b6%e5%a4%b9%20(4)/slf4j-1.7.7/slf4j-jdk14-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
2-lucy-2014-10-02
  2-lucy-2014-10-03
  2-mucy-2014-10-01
  10-maomi-2014-10-05
  13-tom-2014-10-04
  34-jack-2014-10-14

Constants里只有一个DF属性:

package com.citi;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class Constants {
	final static ThreadLocal<DateFormat> DF = new ThreadLocal<DateFormat>() {  
        protected DateFormat initialValue() {    
           return new SimpleDateFormat("yyyy-MM-dd");    
          }    
    }; 
}	

我用HashMap测试Student实现Comparable接口做实验,做不通,有待研究.

实验的日志是搭配是:slf4j.api+slf4j-log4j适配+log4j实现.

因为加了一个slf4j-jdk的适配,因此出现multiple binding,不影响slf4j去绑定log4j.