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