map 排序问题

来源:互联网 发布:林仕鼎 知乎 编辑:程序博客网 时间:2024/05/21 17:39

项目中用于解决并发问题用到 形如以下的 map:
Map<Integer, Player> playerList = Collections
   .synchronizedMap(new HashMap<Integer, Player>());
ConcurrentHashMap<Integer,Player> gamePlayer=
      new ConcurrentHashMap<Integer, Player>();
查阅知 ConcurrentHashMap 本身用于高并发的同步问题,这个之前没有用过。但用到  ConcurrentHashMap时却

发现了排序的问题:

通常map 迭代出来的值 是和put时候是一样的,但 ConcurrentHashMap 却对值 进行了倒序的排列 如:
  ConcurrentHashMap<Integer,Integer> map =new ConcurrentHashMap<Integer, Integer>();
  map.put(2, 2);
  map.put(1, 1);
  map.put(3, 3);
  Iterator<Integer> it = map.keySet().iterator();
  while (it.hasNext()) {
  System.out.println(map.get(it.next()));
 }

打印结果为 3 2 1

但现在需要的值是按put的顺序的,而且map 好像并不能从集合的尾部开始取值。于是要对其进行手动的排序,

由而引出许多问题:

因为没有对map 排过序,最先想到的 还是将map值 取出放出list中,然后进行排序, 按照惯性思维,如果是基

本类型的话,就会用那个 ‘经典的’ 2轮排序法:

  int [] arr = new int[3];
  for (int i = 0; i < arr.length; i++) {
   for (int j = i+1; j < arr.length; j++) {
    ...
   }
   
  }
比较次数 为 n-1 +n-2 + ...

如果list 中是对象的话,一般也是先存入数组,再转为list,再套用上述排序法进行排序:
 public static void main(String[] args) {
  
  P p1 = new P(2);
  P p2 = new P(1);
  P p3 = new P(3);
  
  List<P> list = new ArrayList<P>();
  for (int i = 0; i < 10; i++) {
   list.add(p1);
   list.add(p2);
   list.add(p3);
  }

  Object arr  []  = list.toArray();

  for (int i = 0; i < arr.length; i++) {
   P max = arr[i];
   for (int j = i+1; j < arr.length; j++) {
    P com = arr[j];
    if(max.getId()<com.getId()){
     P tmp = max;
     arr[i] = arr[j];
     arr[j] = tmp;
    }
   }
  }
        }

class P{
 private int id;
 public int getId() {
  return id;
 } 
 public P(int id) {
  this.id = id;
 }
}


其实,我在当初学习了list中可以 删,增的方法后,就写出了如下 很搞的 排序法:

  for (int i = 0; i < list.size(); i++) {
   P max = list.get(i);
   for (int j = i+1; j < list.size(); j++) {
    P com = list.get(j);
    if(max.getId()<com.getId()){
     P tmp = max;
     list.remove(i);
     list.add(i,com);
     list.remove(j);
     list.add(j,tmp);
     continue;
    }
   }
  }

用先remove 再 add 实现了 交换位置,实际上这个方法是没错 可用的,而且我还用了很长时间,但经测试,当

数据量超过1w的时候,速度明显很慢。。。

下面就是本文的重点了,其实和 Arrays.sort();一样,Collections 也提供了本身的排序法,用法如下:

  Collections.sort(list, new Comparator(){
   public int compare(Object a, Object b) {
    int a1 = ((P)a).getId();
    int b1 =  ((P)b).getId();
    if(a1>b1){
     return 1;
    }else if(a1<b1){
     return -1;
    }
    return 0;
   }
  });

传入一个 Comparator的实例,写入比较规则就可以了,上面compare中的那一堆也可以直接换成:
//return (new Integer(((P)b).getId()).compareTo(((P)a).getId()));
看不懂的话 ,百度 .compareTo() 方法。

上述排序法在大数据量情况下,效率 明显高于 我自创的写法,呵呵~
map也同样可以用上面的排序法 ,因为 map 也属于集合,将 list 换成 map.keySet()就可以 实现排序了。
还有一种写法,就是继承并重写 map ,虽然也能实现,但那就太没必要了。。
以后系统已经提供的东西,还是用它的吧。。。

原创粉丝点击