使用LinkedHashMap和Comparator排序器对Map的排序抛砖引玉

liuzyl 2012-09-20 11:56:27
我现在有一个需求,我需要一个map存放 一组person类的信息,包括name,level和age,并且我需要排序,排序之后我可能还要根据name来修改任意person的值,我想过用arrayList,但是arrayList取任意值不方便,需要循环取值,map也不行,map不能排序,
maptree我试过,好像只能按照key值排序,我的key值是用来存放name的,我需要的排序方式是level和age

在网上找了几个小时资料后,我整理出一个方法,使用Map赋值,然后map转成arraylist,arraylist通过Comparator排序,然后再循环给到LinkedHashMap.

网上还有一种方法是用treemap, 先把key和value值反过来,用Preson类做key值,使用key值排序之后再反转treemap

求哪个方法靠谱些,或者高手们给我个好解决方法。

这是Person


public class Person {
/**等级*/
private int level;
/**姓名*/
private String name;
/**年龄*/
private int age;

public Person(int type,String name,int age) {
this.name = name;
this.level = type;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public int getLevel() {
return level;
}

public void setLevel(int level) {
this.level = level;
}

}




这是转换



public static LinkedHashMap<String, Person> getOrder(Map<String, Person> map){
List<Map.Entry<String, Person>> infoIds =new ArrayList<Map.Entry<String, Person>>(map.entrySet());

//排序
Collections.sort(infoIds, new Comparator<Map.Entry<String, Person>>() {
public int compare(Map.Entry<String, Person> o1, Map.Entry<String, Person> o2) {
Person p1 = (Person) o1.getValue();
Person p2 = (Person) o2.getValue();;

if (p1.getLevel() == p2.getLevel()){
return p1.getAge() -p2.getAge();
}else{
return p1.getLevel() - p2.getLevel();
}
}
});

/*转换成新map输出*/
LinkedHashMap<String, Person> newMap = new LinkedHashMap <String, Person>();

for(Map.Entry<String,Person> entity : infoIds){
newMap.put(entity.getKey(), entity.getValue());
}

return newMap;
}




测试:


public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String, Person> map = new HashMap<String, Person>();
map.put("Json", new Person(1,"Json", 20));
map.put("Peter", new Person( 2,"Peter",22));
map.put("Divid", new Person(1,"Divid", 25));
map.put("Aglia", new Person(3,"Aglia", 27));
map.put("Alex", new Person(3,"Alex", 23));
map.put("Molic", new Person(3,"Molic", 22));


LinkedHashMap<String, Person> newMap = getOrder(map);

Iterator<Entry<String, Person>> iter = newMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Person> entry = (Map.Entry<String, Person>) iter.next();

System.out.println( entry.getValue().getName() + "|" + entry.getValue().getLevel() + "|"
+ entry.getValue().getAge()+ "|");
}
}




测试的结果是:
Json|1|20|
Divid|1|25|
Peter|2|22|
Molic|3|22|
Alex|3|23|
Aglia|3|27|
...全文
1530 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
leokelly001 2014-06-04
  • 打赏
  • 举报
回复
使用Map赋值,然后map转成arraylist,arraylist通过Comparator排序
lliiqiang 2014-06-04
  • 打赏
  • 举报
回复
ArrayList即可,遍历,找到其中符合条件的元素,改变它的age.
Kanepan 2012-10-19
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]

为什么不使用ConcurrentSkipListMap?支持comparator.....
[/Quote]

因为不能根据 VALUE 排序
lecoa 2012-10-19
  • 打赏
  • 举报
回复
为什么不使用ConcurrentSkipListMap?支持comparator.....
Kanepan 2012-10-19
  • 打赏
  • 举报
回复
如果你的MAP读比较频繁的话,直接就用LZ第一个的方法,也就新增数据的时候,需要重新排序一下,删除则不需要
如果写比较频繁, 那么就直接用 HashMap(如果有并发安全等需求,用并发版本,避免LinkedHashMap,因为没有官方并发版本)。 然后只在循环读取的时候,排一下序。
牛海朋 2012-09-29
  • 打赏
  • 举报
回复
我都是这么来的

public class KVObject<K, V> {

private K key;
private V value;

/**
* @param key
* @param value
*/
public KVObject(K key, V value) {
this.key = key;
this.value = value;
}

public K getKey() {
return key;
}

public V getValue() {
return value;
}

public void setKey(K key) {
this.key = key;
}

public void setValue(V value) {
this.value = value;
}

@Override
public String toString() {
return "KVObject [key=" + key + ", value=" + value + "]";
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (obj == null) {
return false;
} else if (getClass() != obj.getClass()) {
return false;
} else {
KVObject<?, ?> other = (KVObject<?, ?>) obj;
if (key == other.key && value == other.value) {
return true;
} else if (key != null && value != null && key.equals(other.key)
&& value.equals(other.value)) {
return true;
} else {
return false;
}
}
}

}

public class MapUtil {

public static <K, V> Map<K, V> list2Map(List<KVObject<K, V>> list) {
if (list == null) {
return null;
}
Map<K, V> map = new HashMap<K, V>();
Iterator<KVObject<K, V>> it = list.iterator();
while (it.hasNext()) {
KVObject<K, V> kvObj = it.next();
K key = kvObj.getKey();
V value = kvObj.getValue();
if (map.containsKey(key)) {
throw new RuntimeException(
"Illegal List,one or more KVObect with the same key:"
+ key);
}
map.put(key, value);
}
return map;
}

public static <K, V> List<KVObject<K, V>> map2List(Map<K, V> map) {
if (map == null) {
return null;
}
List<KVObject<K, V>> list = new ArrayList<KVObject<K, V>>();
Set<K> keys = map.keySet();
Iterator<K> it = keys.iterator();
while (it.hasNext()) {
K key = it.next();
V value = map.get(key);
KVObject<K, V> kvObj = new KVObject<K, V>(key, value);
list.add(kvObj);
}
return list;
}

public static <K, V> Map<K, V> sortMap(Map<K, V> map,
Comparator<? super KVObject<K, V>> comparator) {
List<KVObject<K, V>> list = map2List(map);
Collections.sort(list, comparator);
return list2Map(list);
}
}
lf383554330 2012-09-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

这个挺好...但是有个问题,我需要再次排序的话..就要hashmap转成treeset...
那和我的也差不多吧~

引用 2 楼 的回复:

如果一定要用map存的话,要不这样用treeSet实现排序功能,然后遍历treeSet赋给map
Java code
public static void main(String[] args) {
TreeSet<Person> ts……
[/Quote]
嗯, 在map里根据条件排序是没有直接的方法的,这两种方法都是间接排序,不过我个人还是习惯用treeSet,你可以自由选择。
liuzyl 2012-09-27
  • 打赏
  • 举报
回复
这个挺好...但是有个问题,我需要再次排序的话..就要hashmap转成treeset...
那和我的也差不多吧~

[Quote=引用 2 楼 的回复:]

如果一定要用map存的话,要不这样用treeSet实现排序功能,然后遍历treeSet赋给map
Java code
public static void main(String[] args) {
TreeSet<Person> ts = new TreeSet<Person>(new PersonComparator());

ts.add(new Per……
[/Quote]
liuzyl 2012-09-27
  • 打赏
  • 举报
回复
这个太复杂了..效率要高很多么,顶多上百个数据?

[Quote=引用 3 楼 的回复:]

Java code

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
……
[/Quote]
liuzyl 2012-09-27
  • 打赏
  • 举报
回复
使用TreeSet ,不好取啊..我需要随时取出来值,然后修改level,然后再存进去的..
[Quote=引用 4 楼 的回复:]

Java code

public class Person implements Comparable<Person> {
/** 等级 */
private int level;
/** 姓名 */
private String name;
/** 年龄 */
private int age;

public Person(int t……
[/Quote]
chenjwjw 2012-09-25
  • 打赏
  • 举报
回复

public class Person implements Comparable<Person> {
/** 等级 */
private int level;
/** 姓名 */
private String name;
/** 年龄 */
private int age;

public Person(int type, String name, int age) {
this.name = name;
this.level = type;
this.age = age;
}


public Person() {
// TODO Auto-generated constructor stub
}


public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public int getLevel() {
return level;
}

public void setLevel(int level) {
this.level = level;
}


/*@Override*/
public int compareTo(Person o) {
int num = new Integer(this.level).compareTo(new Integer(o.level));
if(num == 0){
return new Integer(this.age).compareTo(new Integer(o.age));
}
return num;
}

}

测试类
public static void main(String[] args) {

TreeSet<Person> set = new TreeSet<Person>();
set.add(new Person(1,"Json", 20));
set.add(new Person( 2,"Peter",22));
set.add(new Person(1,"Divid", 25));
set.add(new Person(3,"Aglia", 27));
set.add(new Person(3,"Alex", 23));
set.add(new Person(3,"Molic", 22));

Iterator<Person> it = set.iterator();
while(it.hasNext()){
Person p =it.next();
System.out.println(p.getName()+"|"+p.getLevel()+"|"+p.getAge());
}

}

raistlic 2012-09-25
  • 打赏
  • 举报
回复

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

/**
*
* @author raistlic
* @date 25/09/2012
*/
public class ValueSortedMap<K, V> implements Map<K, V> {

public static void main(String[] args) {

Map<String, Person> map = new ValueSortedMap<String, Person>(
new Comparator<Person>() {

@Override
public int compare(Person o1, Person o2) {

int result = o1.getLevel() - o2.getLevel();
if( result == 0 )
result = o1.getAge() - o2.getAge();

return result;
}
});
map.put("Json", new Person(1, "Json", 20));
map.put("Peter", new Person(2, "Peter", 22));
map.put("Divid", new Person(1, "Divid", 25));
map.put("Aglia", new Person(3, "Aglia", 27));
map.put("Alex", new Person(3, "Alex", 23));
map.put("Molic", new Person(3, "Molic", 22));


for(String key : map.keySet())
System.out.println(map.get(key));
}

private Map<K, V> proxyMap;
private SortedSet<K> keySet;
private Comparator<? super V> valueComparator;
private Comparator<Map.Entry<K, V>> entryComparator;
public ValueSortedMap(Comparator<? super V> comparator) {

if( comparator == null )
throw new NullPointerException();

this.valueComparator = comparator;
this.proxyMap = new HashMap<K, V>();
this.keySet = new TreeSet<K>(new KComparator(comparator));
this.entryComparator = new EntryComparator(comparator);
}

@Override
public Set<K> keySet() {

return new TreeSet<K>(keySet);
}

@Override
public Collection<V> values() {

List<V> result = new ArrayList<V>(proxyMap.values());
Collections.sort(result, this.valueComparator);
return result;
}

@Override
public Set<Entry<K, V>> entrySet() {

Set<Entry<K, V>> result = new TreeSet<Entry<K, V>>(this.entryComparator);
result.addAll(proxyMap.entrySet());
return result;
}

@Override
public int size() {

return proxyMap.size();
}

@Override
public boolean isEmpty() {

return proxyMap.isEmpty();
}

@Override
public boolean containsKey(Object key) {

return proxyMap.containsKey(key);
}

@Override
public boolean containsValue(Object value) {

return proxyMap.containsValue(value);
}

@Override
public V get(Object key) {

return proxyMap.get(key);
}

@Override
public V put(K key, V value) {

if( key == null )
throw new NullPointerException();
if( value == null )
throw new NullPointerException();

V result = proxyMap.put(key, value);
keySet.add(key);
return result;
}

@Override
@SuppressWarnings("unchecked")
public V remove(Object key) {

keySet.remove((K)key);
return proxyMap.remove(key);
}

@Override
public void putAll(Map<? extends K, ? extends V> m) {

if( m == null )
throw new NullPointerException();

for(K key : m.keySet())
put(key, m.get(key));
}

@Override
public void clear() {

keySet.clear();
proxyMap.clear();
}

private class KComparator implements Comparator<K> {

private final Comparator<? super V> vComparator;
private KComparator(Comparator<? super V> vComparator) {

assert vComparator != null;

this.vComparator = vComparator;
}

@Override
public int compare(K o1, K o2) {

return vComparator.compare(get(o1), get(o2));
}
}

private class EntryComparator implements Comparator<Map.Entry<K, V>> {

private final Comparator<? super V> vComparator;
private EntryComparator(Comparator<? super V> vComparator) {

assert vComparator != null;

this.vComparator = vComparator;
}

@Override
public int compare(Entry<K, V> o1, Entry<K, V> o2) {

return vComparator.compare(o1.getValue(), o2.getValue());
}
}
}

class Person {

private int level;
private String name;
private int age;

public Person(int type, String name, int age) {
this.name = name;
this.level = type;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public int getLevel() {
return level;
}

public void setLevel(int level) {
this.level = level;
}

@Override
public String toString() {

return getName() + "|" + getLevel() + "|" + getAge()+ "|";
}
}


最好是 implements SortedMap<K, V>
没时间改了。
lf383554330 2012-09-22
  • 打赏
  • 举报
回复
如果一定要用map存的话,要不这样用treeSet实现排序功能,然后遍历treeSet赋给map
public static void main(String[] args) {
TreeSet<Person> ts = new TreeSet<Person>(new PersonComparator());

ts.add(new Person(1, "Json", 20));
ts.add(new Person(2, "Peter", 22));
ts.add(new Person(1, "Divid", 25));
ts.add(new Person(3, "Aglia", 27));
ts.add(new Person(3, "Alex", 23));
ts.add(new Person(3, "Molic", 22));

Map<String, Person> map = new HashMap<String, Person>();

for (Iterator<Person> iterator = ts.iterator(); iterator.hasNext();) {
Person p = (Person) iterator.next();
map.put(p.getName(), p);
System.out.println(p.getName() + "|" + p.getLevel() + "|"
+ p.getAge());
}
}
}

class PersonComparator implements Comparator<Person> {

@Override
public int compare(Person p1, Person p2) {
if (p1.getLevel() == p2.getLevel()) {
return p1.getAge() - p2.getAge();
}

return p1.getLevel() - p2.getLevel();
}

lz考虑下
liuzyl 2012-09-21
  • 打赏
  • 举报
回复
求高手啊~

62,612

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧