排序HashMap,同时保持重复 [英] Sorting a HashMap, while keeping duplicates

查看:95
本文介绍了排序HashMap,同时保持重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图以两种方式对 HashMap 进行排序。默认方式:按字母顺序按值,第二种方式:数字按键,其中较高的数字在顶部。我已经搜索了,但是找不到任何东西的主题,我找到的,不工作。如果不可能对它们进行排序(我希望顶部具有最高键的人,随着人们具有较低的键而减小,然后按字母顺序对所有其余部分进行排序(以0作为其键的人)。



这是我到目前为止所尝试的:

  private HashMap< String,Integer> ; userGains = new HashMap< String,Integer>(); 

public void sortGains(int skill,int user){
userGains.put(users.get(user).getUsername ,users.get(user).getGainedExperience(skill));
HashMap< String,Integer> map = sortHashMap(userGains);
for(int i = 0; i< map.size ; i ++){
Application.getTrackerOutput()。getOutputArea(skill).append(users.get(user).getUsername()+gains+ map.get(users.get(user).getUsername )+experience in+ getSkillName(skill)+.\\\
);
}
}

public LinkedHashMap< String,Integer> sortHashMap(HashMap& ,Integer> passedMap){
List< String> mapKeys = new ArrayList< String>(passedMap.keySet());
List< Integer> mapValues = new ArrayList< Integer>(passedMap.values());
LinkedHashMap< String,Integer> sortedMap = new LinkedHashMap< String,Integer>();

Collections.sort(mapValues);
Collections.sort(mapKeys);

迭代器< Integer> it $ = mapValues.iterator();
while(it $ .hasNext()){
Object val = it $ .next();
Iterator< String> keyIt = mapKeys.iterator();
while(keyIt.hasNext()){
Object key = keyIt.next();
String comp1 = passedMap.get(key).toString();
String comp2 = val.toString();
if(comp1.equals(comp2)){
passedMap.remove(key);
mapKeys.remove(key);
sortedMap.put((String)key,(Integer)val);
break;
}
}
}
return sortedMap;
}

因为你不能运行这里是一个SSCCE:

  private HashMap< String,Integer> userGains = new HashMap< String,Integer>(); 

private Object [] [] testUsers = {{Test user,15},{Test,25},{Hello,11},{I'm a user ,21},{不是你!,14},{是我!,45},{哦,好吧,对不起,混乱,0},{很好。 ,0}};

public static void main(String [] arguments){
new Sorting()。sortGains();
}

public void sortGains(){
for(Object [] test:testUsers){
userGains.put((String)test [0], Integer)test [1]);
}
HashMap< String,Integer> map = sortHashMap(userGains);
for(int i = 0; i< map.size(); i ++){
System.out.println(testUsers [i] [0] +getting+ map.get [i] [0])+经验。
}
}

public LinkedHashMap< String,Integer> sortHashMap(HashMap< String,Integer> passedMap){
List< String> mapKeys = new ArrayList< String>(passedMap.keySet());
List< Integer> mapValues = new ArrayList< Integer>(passedMap.values());
LinkedHashMap< String,Integer> sortedMap = new LinkedHashMap< String,Integer>();

Collections.sort(mapValues);
Collections.sort(mapKeys);

迭代器< Integer> it $ = mapValues.iterator();
while(it $ .hasNext()){
Object val = it $ .next();
Iterator< String> keyIt = mapKeys.iterator();
while(keyIt.hasNext()){
Object key = keyIt.next();
String comp1 = passedMap.get(key).toString();
String comp2 = val.toString();
if(comp1.equals(comp2)){
passedMap.remove(key);
mapKeys.remove(key);
sortedMap.put((String)key,(Integer)val);
break;
}
}
}
return sortedMap;
}

程序的输出目前是:

 测试用户获得了15次经验。 
测试已获得25经验。
你好,获得11点经验。
我是一个用户获得21经验。
不,你不是!获得14经验。
是的,我是!获得45经验。
哦,好吧。对不起,困惑。获得0经验。
这是很好的。获得0经验。

当我需要时:

 是的,我是!获得45经验。 //在这里开始数字排序,按最高键。 
测试已获得25经验。
我是一个用户获得21经验。
测试用户获得15经验。
不,你不是!获得14经验。
你好,获得11点经验。
这是很好的。获得0经验。 //如果可能的话,在这里开始字母排序。
哦,好吧。对不起,困惑。获得0经验。

任何洞察力?

解决方案

您在显示值时发生错误。

  HashMap< String,Integer& map = sortHashMap(userGains); 
for(int i = 0; i< map.size(); i ++){
System.out.println(testUsers [i] [0] +getting+ map.get [i] [0])+经验。
}

您需要显示地图的值而不是原始数组的值。 p>

这应该可以:

  HashMap< String,Integer> map = sortHashMap(userGains); 
for(Entry< String,Integer> entry:map.entrySet()){
System.out.println(entry.getKey()+getting+ entry.getValue()+experience。 );
}

您只需逆转订单。此外,我建议对 Map 而不是声明 HashMap LinkedHashMap 避免自己和他人混淆。此外,使用 Comparable 可以更简单地完成排序。这是一个改进:

  private Map< String,Integer> userGains = new HashMap< String,Integer>(); 

private Object [] [] testUsers = {{Test user,15},{Test,25},{Hello,11},{I'm a user ,21},{不是你!,14},{是我!,45},{哦,对不起,混乱。 ,0}};

public static void main(String [] arguments){
new Sorting()。sortGains();
}

public void sortGains(){
for(Object [] test:testUsers){
userGains.put((String)test [0], Integer)test [1]);
}

映射< String,Integer> map = createSortedMap(userGains);

for(Entry< String,Integer> entry:map.entrySet()){
System.out.println(entry.getKey()+gains+ entry.getValue +经验。
}
}

public Map< String,Integer> createSortedMap(Map< String,Integer> passedMap){
List< Entry< String,Integer> entryList = new ArrayList< Entry< String,Integer>>(passedMap.entrySet());

Collections.sort(entryList,new Comparator< Entry< String,Integer>>(){

@Override
public int compare(Entry& Integer> e1,Entry< String,Integer> e2){
if(!e1.getValue()。equals(e2.getValue())){
return e1.getValue()。compareTo .getValue())* -1; // * -1颠倒顺序
} else {
return e1.getKey()。compareTo(e2.getKey());
}
}
});

映射< String,Integer> orderedMap = new LinkedHashMap< String,Integer>();

for(Entry< String,Integer> entry:entryList){
orderedMap.put(entry.getKey(),entry.getValue());
}

return orderedMap;
}


I'm trying to sort a HashMap in two ways. The default way: alphabetically by the value, the second way: numerically by the key, with the higher number being at the top. I have searched around but can't find anything on the subject, and what I do find, doesn't work. If it's not possible to sort both of them (I want the person with the highest key at the top, decreasing as people have lower keys, then alphabetically sort all of the rest (the people with 0 as their key).

Here's what I've tried so far:

private HashMap<String, Integer> userGains = new HashMap<String, Integer>();

public void sortGains(int skill, int user) {
    userGains.put(users.get(user).getUsername(), users.get(user).getGainedExperience(skill));
    HashMap<String, Integer> map = sortHashMap(userGains);
    for (int i = 0; i < map.size(); i++) {
        Application.getTrackerOutput().getOutputArea(skill).append(users.get(user).getUsername() + " gained " + map.get(users.get(user).getUsername()) + "  experience in " + getSkillName(skill) + ".\n");
    }
}

public LinkedHashMap<String, Integer> sortHashMap(HashMap<String, Integer> passedMap) {
    List<String> mapKeys = new ArrayList<String>(passedMap.keySet());
    List<Integer> mapValues = new ArrayList<Integer>(passedMap.values());
    LinkedHashMap<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();

    Collections.sort(mapValues);
    Collections.sort(mapKeys);

    Iterator<Integer> it$ = mapValues.iterator();
    while (it$.hasNext()) {
        Object val = it$.next();
        Iterator<String> keyIt = mapKeys.iterator();
        while (keyIt.hasNext()) {
            Object key = keyIt.next();
            String comp1 = passedMap.get(key).toString();
            String comp2 = val.toString();
            if (comp1.equals(comp2)) {
                passedMap.remove(key);
                mapKeys.remove(key);
                sortedMap.put((String) key, (Integer) val);
                break;
            }
        }
    }
    return sortedMap;
}

Since you cannot run that here is an SSCCE:

private HashMap<String, Integer> userGains = new HashMap<String, Integer>();

private Object[][] testUsers = { { "Test user", 15 }, { "Test", 25 }, { "Hello", 11 }, { "I'm a user", 21 }, { "No you're not!", 14 }, { "Yes I am!", 45 }, { "Oh, okay.  Sorry about the confusion.", 0 }, { "It's quite alright.", 0 } };

public static void main(String[] arguments) {
    new Sorting().sortGains();
}

public void sortGains() {
    for (Object[] test : testUsers) {
        userGains.put((String) test[0], (Integer) test[1]);
    }
    HashMap<String, Integer> map = sortHashMap(userGains);
    for (int i = 0; i < map.size(); i++) {
        System.out.println(testUsers[i][0] + " gained " + map.get(testUsers[i][0]) + "  experience.");
    }
}

public LinkedHashMap<String, Integer> sortHashMap(HashMap<String, Integer> passedMap) {
    List<String> mapKeys = new ArrayList<String>(passedMap.keySet());
    List<Integer> mapValues = new ArrayList<Integer>(passedMap.values());
    LinkedHashMap<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();

    Collections.sort(mapValues);
    Collections.sort(mapKeys);

    Iterator<Integer> it$ = mapValues.iterator();
    while (it$.hasNext()) {
        Object val = it$.next();
        Iterator<String> keyIt = mapKeys.iterator();
        while (keyIt.hasNext()) {
            Object key = keyIt.next();
            String comp1 = passedMap.get(key).toString();
            String comp2 = val.toString();
            if (comp1.equals(comp2)) {
                passedMap.remove(key);
                mapKeys.remove(key);
                sortedMap.put((String) key, (Integer) val);
                break;
            }
        }
    }
    return sortedMap;
}

The output of the program is currently:

Test user gained 15  experience.
Test gained 25  experience.
Hello gained 11  experience.
I'm a user gained 21  experience.
No you're not! gained 14  experience.
Yes I am! gained 45  experience.
Oh, okay.  Sorry about the confusion. gained 0  experience.
It's quite alright. gained 0  experience.

When I need it to be:

Yes I am! gained 45  experience. // start numeric sorting here, by highest key.
Test gained 25  experience.
I'm a user gained 21  experience.
Test user gained 15  experience.
No you're not! gained 14  experience.
Hello gained 11  experience.
It's quite alright. gained 0  experience. // start alphabetical sorting here, if possible.
Oh, okay.  Sorry about the confusion. gained 0  experience.

Any insight?

解决方案

You made a mistake in displaying the values.

HashMap<String, Integer> map = sortHashMap(userGains);
for (int i = 0; i < map.size(); i++) {
    System.out.println(testUsers[i][0] + " gained " + map.get(testUsers[i][0]) + "  experience.");
}

You need to display the map's values instead of the original array's values.

This should do:

HashMap<String, Integer> map = sortHashMap(userGains);
for (Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " gained " + entry.getValue() + "  experience.");
}

You only have to reverse the order. Further I recommend to declare against Map instead of HashMap or LinkedHashMap to avoid confusion by yourself and others. Also your sorting can simpler be done with a Comparable. Here's an improvement:

private Map<String, Integer> userGains = new HashMap<String, Integer>();

private Object[][] testUsers = { { "Test user", 15 }, { "Test", 25 }, { "Hello", 11 }, { "I'm a user", 21 }, { "No you're not!", 14 }, { "Yes I am!", 45 }, { "Oh, okay.  Sorry about the confusion.", 0 }, { "It's quite alright.", 0 } };

public static void main(String[] arguments) {
    new Sorting().sortGains();
}

public void sortGains() {
    for (Object[] test : testUsers) {
        userGains.put((String) test[0], (Integer) test[1]);
    }

    Map<String, Integer> map = createSortedMap(userGains);

    for (Entry<String, Integer> entry : map.entrySet()) {
        System.out.println(entry.getKey() + " gained " + entry.getValue() + "  experience.");
    }
}

public Map<String, Integer> createSortedMap(Map<String, Integer> passedMap) {
    List<Entry<String, Integer>> entryList = new ArrayList<Entry<String, Integer>>(passedMap.entrySet());

    Collections.sort(entryList, new Comparator<Entry<String, Integer>>() {

        @Override
        public int compare(Entry<String, Integer> e1, Entry<String, Integer> e2) {
            if (!e1.getValue().equals(e2.getValue())) {
                return e1.getValue().compareTo(e2.getValue()) * -1; // The * -1 reverses the order.
            } else {
                return e1.getKey().compareTo(e2.getKey());
            }
        }
    });

    Map<String, Integer> orderedMap = new LinkedHashMap<String, Integer>();

    for (Entry<String, Integer> entry : entryList) {
        orderedMap.put(entry.getKey(), entry.getValue());
    }

    return orderedMap;
}

这篇关于排序HashMap,同时保持重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆