【问题标题】:Sorting elements of a collection that has a hashMap Values elements - UnsupportedOperation Exception对具有 hashMap 值元素的集合的元素进行排序 - UnsupportedOperation 异常
【发布时间】:2017-04-28 09:14:21
【问题描述】:

我有一个排序方法,可以对不同类型的集合进行排序。我尝试对 Set、ArrayList、List 和 HashMap 的值的集合进行排序。除了返回 UOE 的 hashMap.values() 集合之外,所有集合都已正确排序。我调试了代码,问题出在以下行:“numbers.add(a[k]);”你知道如何让我的排序方法成功地对hashMap.values() 集合进行排序吗? 代码如下:

public void sort(Collection<NamedValue> numbers)

{
    try
    {
        NamedValue[] a = numbers.toArray(new NamedValue[numbers.size()]) ; 
        boolean swapped = true;
        int j = 0;
        NamedValue temp;
        while (swapped) {
            swapped = false;
            j++;
            for (int i = 0; i < a.length - j; i++) {
                if (a[i] != null && a[i].compareTo(a[i+1]) == 1)
                {
                    temp = a[i];
                    a[i] = a[i + 1];
                    a[i + 1] = temp;
                    swapped = true;
                }
            }   
        } 
        numbers.clear();
        for (int k=0; k<a.length; k++) {
            numbers.add(a[k]);
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

主代码:

    List<NamedValue> numbers = Arrays.asList(new NamedValue("One", 1), /**/
            new NamedValue("Three", 3), /**/
            new NamedValue("Four", 4), /**/
            new NamedValue("Two", 2), /**/
            new NamedValue("Five", 5));

    Map<String, NamedValue> numbersMap = new HashMap<String, NamedValue>();
    for (NamedValue value: numbers)
        numbersMap.put(value.Name(), value);
    System.out.println("numbersMap = " + numbersMap);

    Map<String, Collection<NamedValue>> collections = new HashMap<String, 
    Collection<NamedValue>>();
    collections.put("ArrayList", numbersArrayList);
    collections.put("List", numbersList);
    collections.put("Set", numbersSet);
    collections.put("Map values", numbersMap.values());

    for (String key: collections.keySet())
    {
        Collection<NamedValue> coll = collections.get(key);
        lab.sort(coll);
        System.out.println("Sorted " + key + " = " + coll);
    }

所以我有一个 HashMap 集合,对于这张地图中的每个集合,我想对元素进行排序。其中一个集合包含 numbersMap 集合的值。如何使我的排序方法对所有这些集合( hashMap.values() 集合)进行排序?

【问题讨论】:

  • AbstractCollection#adddocumentation 中描述的可选方法。这意味着并非所有集合都必须支持它。显然HashMap#values 生成的集合不支持它,如here 所述
  • 如果您考虑在 Map 的情况下在这里执行的操作,那么它失败是有道理的。您从地图中获取值,对值进行排序,清除整个地图(删除所有值 键),然后将值添加回地图(不带键)...。重要的这里的事情是文档中的这一行集合由地图支持,因此对地图的更改会反映在集合中,反之亦然。
  • 我觉得我解释得不够好。我尝试清除集合,而不是地图。我在描述中添加了一段主代码。
  • 那段代码实际上让问题更清楚了。但是,答案还是一样的:HashMap#values 不支持add 方法。除此之外,看看你是否能弄清楚这里发生了什么:Map&lt;Integer,Integer&gt; map = new HashMap&lt;&gt;(); map.put(1, 1); map.put(2, 2); map.put(3, 3); Collection&lt;Integer&gt; values = map.values(); values.clear(); map.forEach((k,v)-&gt; System.out.println(k + " " + v));

标签: java sorting hashmap


【解决方案1】:

您不能将项目添加到地图的值集合中

来自 java.util.HashMap.values() 操作的 java 文档:

集合 java.util.HashMap.values() 返回此映射中包含的值的集合视图。集合由地图支持,因此对地图的更改会反映在集合中,反之亦然。如果在对集合进行迭代时修改了映射(通过迭代器自己的删除操作除外),则迭代的结果是不确定的。该集合支持元素移除,即通过 Iterator.remove、Collection.remove、removeAll、retainAll 和 clear 操作从映射中移除相应的映射。 不支持 add 或 addAll 操作。

【讨论】:

    【解决方案2】:

    HashMap 的情况有所不同,因为在 hashmap 中我们采用值键对,因此如果您需要对 hash map 进行排序,我们可以根据 key 对其进行排序。 Arraylist 或 List 不在键值形式中,因此您的排序方法在那里工作。

    【讨论】:

    • 当您真正开始思考为什么无法对HashMap#values 集合进行排序时,您确实需要考虑排序的内容和方式。然后这个答案突然变得更有意义了。我鼓励你改写你的答案并解释一下。
    猜你喜欢
    • 2013-06-10
    • 2022-11-04
    • 2012-10-06
    • 2021-08-06
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    • 2010-12-11
    • 2021-07-14
    相关资源
    最近更新 更多