map 排序问题

原创 2012年03月22日 20:59:35

项目中用于解决并发问题用到 形如以下的 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 ,虽然也能实现,但那就太没必要了。。
以后系统已经提供的东西,还是用它的吧。。。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

ConcurrentHashMap 浅层次总结

学习了 ConcurrentHashMap 的源码,不由地为设计者的思想点赞,现在时间有限,先总结一些我觉得比较有用的知识点,先占个坑,等有时间再详细分析源码。Java 内存模型重排序 编译器生成指令...

hashtable、hashmap、ConcurrentHashMap、treemap的区别

本人原创,转载请注明出处! 本人QQ:530422429,欢迎大家指正、讨论。 欢迎访问: 西北工业大学 - 大数据与知识管理研究室 (Northwestern Polytechnical Un...

HashMap与ConcurrentHashMap的区别

从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心。 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,...

将一数组乱序排列的三种方法

游戏中遇到这样的问题,需要将一组已知的数据打乱,按照以前和现在的做法,总结了以下方法。 方法一,最笨的菜鸟方法,也是容易想到的(幸好我没想过这种方法 :)) 从已知数组中随机一个数,然后加入到另一...

map容器的排序问题

看了好多人写的对map的排序 看得不太懂吧  自己写一些 map set multiset 三个容器都是 放进去 都是事先都要排序的 所以 erase insert find操作都是二分 复杂度都是l...

Java中Map.keySet()返回值遍历的排序问题

很多时候大家都喜欢用HashMap,但是我们在遍历HashMap时获取的顺序却是乱序的,如何解决呢?看下文 > HashMap.keySet()方法,而这个方法返回的Set结果,里面的数据是乱序排放...

关于java中Map排序问题

我们在应用Map中排序问题时,会面临很多问题(比如选择哪种类型的Map应用,如何实现按照自己特定要求进行排序等)。 1 什么是Map 在数组中我们是通过数组下标来对其内容索引的,而在Map...

【Stackoverflow好问题】Map<Key,Value>基于Value值排序

问题 Map如何基于Value值排序 精华回答 方法1: 使用TreeMap,可以参考下面的代码 public class Testing { publ...

map key value的排序问题

一、 Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等。         TreeMap:基于红黑树(Red-Bla...

由2个值组合成key的STL map排序问题

某网友问:“map中怎么设置多个key值进行排序?”   在C++中,map是典型的关联容器或者叫映射容器(associative container),其中的每一个元素都是由key-value这...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)