问题描述
{
"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
比较器来代替之前的比较器。示例:
-
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
-
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