在书写程序的过程中,常常需要对map的key或者value进行排序,Java本身没有提供对map排序的方法,下面的代码展示如何手动对map进行排序
1、按Key排序
jdk内置的java.util包的TreeMap<K,V>可以实现对Key的排序,通过构造方法中传入比较器Comparator即可实现,这里Comparator类型输入的泛型参数是K的超类或本身,即TreeMap(Comparator<? super K> comparator)
相关代码
public class MapSortDemo {
public static void main(String[] args) {
Map<String, String> map = new TreeMap<String, String>();
map.put("KFC", "kfc");
map.put("WNBA", "wnba");
map.put("NBA", "nba");
map.put("CBA", "cba");
Map<String, String> resultMap = sortMapByKey(map); //按Key进行排序
for (Map.Entry<String, String> entry : resultMap.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
/**
* 使用 Map按key进行排序
* @param map
* @return
*/
public static Map<String, String> sortMapByKey(Map<String, String> map) {
if (map == null || map.isEmpty()) {
return null;
}
Map<String, String> sortMap = new TreeMap<String, String>(
new MapKeyComparator());
sortMap.putAll(map);
return sortMap;
}
}
比较器类
class MapKeyComparator implements Comparator<String>{
@Override
public int compare(String str1, String str2) {
return str1.compareTo(str2);
}
}
2、按Value排序
在很多场景下,需要对value排序,Java无法直接实现对map的value的排序,因此需要借助其他数据结构来进行排序。这里使用Collections
的sort
方法,将map转化为list结构,对list进行排序,之后在把list中数据装回map,达到排序目的。在装回map过程中,使用LinkedHashMap
保证装回的顺序与list一致。
例如,我们需要对一些多个圆形轨道上物体的位置进行排序,每个物体都有一个位置属性,位置包含所处的轨道和物体的初始角度,现在要求只按照初始角度进行从小到大的排序。
代码如下
/**
* poisiton是一个map,保存每个物体对应的位置
*/
Map<E, Position> sortedMap = new LinkedHashMap<E, Position>();
List<Map.Entry<E, Position>> entryList = new ArrayList<Map.Entry<E, Position>>(position.entrySet()); //先转为entrySet,在转为List
Collections.sort(entryList, new MapValueComparator<E>());
Iterator<Entry<E, Position>> iter = entryList.iterator();
Map.Entry<E, Position> tmpEntry = null;
while (iter.hasNext()) {
tmpEntry = iter.next();
sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue()); //add sorted object in map
}
/**
* 比较器类
* 根据轨道物体对象的初始角度对position映射进行升序排序
*
* @param <E> 轨道物体类型
*/
class MapValueComparator<E> implements Comparator<Map.Entry<E, Position>> {
@Override
public int compare(Entry<E, Position> o1, Entry<E, Position> o2) {
double a1 = o1.getValue().getAngle();
double a2 = o2.getValue().getAngle();
/*
* compare函数返回的数值正负遵循规则:
* compare(a,b)
* 一切以升序排列,如果 a 与 b 比较返回正数,说明a应该排在b后面,即a比b大
* 如果 a b比较返回负数,说明a小于b,a排在b前面
*/
if(a1 > a2) return 1; //a1角度大于a2,返回正数
else if(a1 < a2) return -1;
if(Math.abs(a1 - a2) < 1e-10) return 0;
return 0;
}
}
这里的代码说明如果value是一个类,那么可以针对类中某一个具体属性进行排序,也可综合考虑多个属性进行排序。
参考文章
网友评论