微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在不改变值顺序的情况下反转 TreeMap 的键顺序?

如何解决如何在不改变值顺序的情况下反转 TreeMap 的键顺序?

我有一个 TreeMap 像这样:

{
    "one": "First option","two": "Second option","three": "Third option","four": "Last option"
}

我想重新调用这个对象,以便输出是这样的:

{
    "four": "First option","three": "Second option","two": "Third option","one": "Last option"
}

我正在查看来自 apache 的一些公共集合实用程序,但没有立即看到任何可以奏效的东西。

没有一堆循环的最简洁的写法是什么?

解决方法

我认为只能使用 LinkedHashMap 来存储这样的列表,因为它不是按字母顺序排列的。但是 LinkedHashMap 保持元素添加的顺序,所以没问题。

我认为没有什么比将所有映射条目(可通过 entrySet() 方法获得)放入 ArrayList 然后通过迭代此数组以相反的顺序将它们添加到另一个映射更简单的事情了。如果是反向迭代器,我们可以派生一个类来交换它们,但看起来没有迭代器可以反向移动,所以覆盖不是一个选项。

在创建映射后更改键的哈希码不会改变顺序,因为桶已经存在。但是,它可能会阻止地图正常工作。

,

这意味着您的映射函数(首先如何生成 Map)是错误的。

无论您使用哪种 Map 实现,保存键值对都是合适的数据结构。通过反转/改组具有不同值的键来扭曲键值对,违背此数据结构的基本原则是没有意义的。

在这种情况下,如果Key-Value和松散相关,我们可以考虑把这个放在两个不同的List中吗?根据要求在需要时再次映射。

此外,three 将放置在您的 TreeMap 中的 two 之前。不是这样组织的吗*?

,

反转地图中键的顺序与创建新地图相同。为此,首先创建一个包含当前地图条目的列表,然后一次在两个方向上迭代该列表并collect 一个新地图。这对于 LinkedHashMap 来说已经足够了,对于 TreeMap,您必须另外指定一个 reversed 比较器来代替之前的比较器。示例:

  1. TreeMap

    TreeMap<Integer,String> map1 =
            new TreeMap<>(Comparator.naturalOrder()) {{
                put(1,"First option");
                put(2,"Second option");
                put(3,"Third option");
                put(4,"Last option");
            }};
    
    List<Map.Entry<Integer,String>> list1 = new ArrayList<>(map1.entrySet());
    
    TreeMap<Integer,String> map2 = IntStream.range(0,list1.size())
            .boxed().collect(Collectors.toMap(
                    // from the end to the beginning
                    i -> list1.get(list1.size() - i - 1).getKey(),// from the beginning to the end
                    i -> list1.get(i).getValue(),// merge duplicates,if any
                    (s1,s2) -> s1 + "," + s2,// reversed comparator to the one that was before
                    () -> new TreeMap<>(map1.comparator().reversed())));
    
    // output
    map2.forEach((k,v) -> System.out.println(k + " : " + v));
    //4 : First option
    //3 : Second option
    //2 : Third option
    //1 : Last option
    

  2. LinkedHashMap

    LinkedHashMap<String,String> map3 =
            new LinkedHashMap<>() {{
                put("one","First option");
                put("two","Second option");
                put("three","Third option");
                put("four","Last option");
            }};
    
    List<Map.Entry<String,String>> list2 = new ArrayList<>(map3.entrySet());
    
    LinkedHashMap<String,String> map4 = IntStream.range(0,list2.size())
            .boxed().collect(Collectors.toMap(
                    // from the end to the beginning
                    i -> list2.get(list2.size() - i - 1).getKey(),// from the beginning to the end
                    i -> list2.get(i).getValue(),LinkedHashMap::new));
    
    // output
    map4.forEach((k,v) -> System.out.println(k + " : " + v));
    //four : First option
    //three : Second option
    //two : Third option
    //one : Last option
    

另见:How do I sort two arrays in relation to each other?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。