Java - 列表排序不起作用

时间:2013-10-26 09:22:04

标签: java list hashmap compare comparable

我正在尝试通过对其键进行排序来对哈希映射进行排序,但它不起作用。 排序标准由列表的长度给出,该列表是hashmap的值。 请参阅下面的代码并进行一些单元测试。

类别:

package com.fabri.interpreter.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

import com.fabri.interpreter.VerbExpr;
import com.fabri.interpreter.ObjectExpr;

public class Environment {

    private HashMap<VerbExpr, List<ObjectExpr>> map = new HashMap<VerbExpr, List<ObjectExpr>>();

    public List<ObjectExpr> eval(VerbExpr verb) {
        return map.get(verb);
    }

    public void put(VerbExpr verb, ObjectExpr words) {
        List<ObjectExpr> values;
        if(map.get(verb) == null) 
            values = new ArrayList<ObjectExpr>();
        else
            values = map.get(verb);
        values.add(words);
        map.put(verb, values);
    }

    public HashMap<VerbExpr, List<ObjectExpr>> getMap() {
        return map;
    }

    public void sort() {
        List<VerbExpr> keys = new ArrayList<VerbExpr>(map.keySet());
        Collections.sort(keys, new Comparator<VerbExpr>() {
            @Override
            public int compare(VerbExpr verb1, VerbExpr verb2) {
                return map.get(verb1).size()-map.get(verb2).size();
            }
        });
        HashMap<VerbExpr, List<ObjectExpr>> sortedMap = new HashMap<VerbExpr, List<ObjectExpr>>();
        for(VerbExpr verb : keys) {
            sortedMap.put(verb, map.get(verb));
        }
        map = sortedMap;
    }

}

测试类:

package com.fabri.interpreter.util;

import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import com.fabri.interpreter.ObjectExpr;
import com.fabri.interpreter.VerbExpr;
import com.fabri.interpreter.WordExpr;

public class TestEnvironment {

    private Object[] verbExprs;

    @Before
    public void setUp() {
        Environment env = new Environment();
        List<WordExpr> words1 = new ArrayList<WordExpr>();
        words1.add(new WordExpr("american"));
        words1.add(new WordExpr("italian"));
        env.put(new VerbExpr("was"), new ObjectExpr(words1));
        List<WordExpr> words2 = new ArrayList<WordExpr>();
        words2.add(new WordExpr("zero"));
        words2.add(new WordExpr("one"));
        words2.add(new WordExpr("two"));
        env.put(new VerbExpr("is"), new ObjectExpr(words2));
        env.sort();
        verbExprs = env.getMap().keySet().toArray();
    }

    @Test
    public void testEnvironment() {
        assertTrue(((VerbExpr)verbExprs[0]).equals("is"));
        assertTrue(((VerbExpr)verbExprs[1]).equals("was"));
    }

}

2 个答案:

答案 0 :(得分:2)

普通的哈希映射本质上是无序的。您无法对它们进行排序,也不能假设在迭代它们时检索条目的顺序。选项:

  • 如果您想按键排序,请使用TreeMap
  • 如果您想保留广告订单顺序,请使用LinkedHashMap(这就是您假定的sort方法)
  • 创建一个键/值对列表并对其进行排序。

答案 1 :(得分:0)

正如jon所说,我建议保留一个有序的密钥列表,并使用它来访问固有的无序哈希映射。