如何对包含多个键值对的HashMap的ArrayList进行排序?

15

我需要使用一个ArrayList,其中包含多个预定义键值对的HashMap,调用外部API。 例如:

ArrayList<HashMap<String, String>> arrayListHashMap = new ArrayList<HashMap<String, String>>();

    {
        HashMap hashMap = new HashMap<String, String>();
        hashMap.put("key", "A key");
        hashMap.put("value", "B value");
        arrayListHashMap.add(hashMap);
    }

    {
        HashMap hashMap = new HashMap<String, String>();
        hashMap.put("key", "B key");
        hashMap.put("value", "A value");
        arrayListHashMap.add(hashMap);
    }

现在我需要根据“value”键的内容对这个结构进行排序。此排序将导致“key = B key / value = A value”条目成为arrayListHashMap中的第一个条目。

非常感谢任何帮助。

HJW

3个回答

41

你需要实现一个Comparator<HashMap<String, String>>或者更为通用的Comparator<Map<String, String>>,该比较器只提取与value键相关联的值,然后使用Collections.sort。以下是示例代码(可以根据你想要排序的键进行通用化):

class MapComparator implements Comparator<Map<String, String>>
{
    private final String key;

    public MapComparator(String key)
    {
        this.key = key;
    }

    public int compare(Map<String, String> first,
                       Map<String, String> second)
    {
        // TODO: Null checking, both for maps and values
        String firstValue = first.get(key);
        String secondValue = second.get(key);
        return firstValue.compareTo(secondValue);
    }
}

...
Collections.sort(arrayListHashMap, new MapComparator("value"));

非常感谢您的快速回复。 - Harald Wilhelm
你好,如果我想按照一些自定义的标准进行排序怎么办?比如我有一个值叫做TEST,我希望以这样的方式对列表进行排序,即所有值为TEST的项目都排在前面,然后是其他所有项目。所以基本上,如果我有一个大小为10的列表,并且其中包含TEST值2次,分别在位置5和8,那么我希望它们都排在最前面。其他值将在其后。请问如何实现? - Scorpion
@Scorpion:然后你编写一个比较器,检查TEST并始终将其视为早于任何其他值。你觉得哪一部分有困难?(这可能最好作为一个新问题...) - Jon Skeet
1
@JonSkeet 你好,我遇到了类似的情况,我正在按照您建议的做,但仍然出现“类型Collections中的方法sort(List<T>, Comparator<? super T>)对于参数(ArrayList<HashMap>,MapComparator)不适用”的错误。有什么解决办法吗? - shubham gupta
@shubhamgupta:没有看到具体的代码,很难知道问题所在。我建议您提出一个新问题,并提供一个简短但完整的示例来演示问题。 - Jon Skeet

1
您可以使用以下解决方案来实现它:

arrayListHashMap.sort(Comparator.comparing(m -> m.get("value"), Comparator.nullsLast(Comparator.naturalOrder())));

0

(这不是对提出的问题的答案 - Jon已经做过了 - 但评论框太小了。)

你的数据结构看起来像是误解了映射(以及你的示例中的哈希映射)的键值结构。

一个Map可以包含任意数量的键,每个键也可以有一个值。键值对由Map.Entry给出(可以通过映射的entrySet()方法获得)。如果您想按键排序,只需使用SortedMap(如TreeMap)而不是通常的HashMap即可。

你正在通过每个HashMap模拟单独的条目,然后将它们全部放入ArrayList中... :-/

这是我在你的示例中所做的:

Map<String, String> map = new TreeMap<String, String>();
map.put("B key", "B value");
map.put("A key", "B value");

System.out.println(map); // already sorted

1
谢谢你的回答。我需要提供外部API - 这个想法不是我的。我理解的是,他们模拟了类似于数据库查询结果的东西。ArrayList是查询结果,每个HashMap是一条记录,每个条目都是字段名和它的值。"key"是一个字段,"value"是另一个字段。看起来我应该在示例中使用不同的名称来表示这两个条目。只需使用"field1"和"field2"代替"key"和"value"即可。对于造成的困惑,我很抱歉。 - Harald Wilhelm
外部API实际上应该使用JavaBean列表。 - BalusC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接