Java有序地图

Wha*_*sit 300 java collections

在Java中,是否有一个对象用作存储和访问键/值对的Map,但是可以返回一个有序的键列表和一个有序的值列表,这样键和值列表的顺序相同?

因此,作为代码解释,我正在寻找像我的虚构OrderedMap一样的东西:

OrderedMap<Integer, String> om = new OrderedMap<>();
om.put(0, "Zero");
om.put(7, "Seven");

String o = om.get(7); // o is "Seven"
List<Integer> keys = om.getKeys();
List<String> values = om.getValues();

for(int i = 0; i < keys.size(); i++)
{
    Integer key = keys.get(i);
    String value = values.get(i);
    Assert(om.get(key) == value);
}
Run Code Online (Sandbox Code Playgroud)

dme*_*ter 375

SortedMap的接口(与实施TreeMap的)应该是你的朋友.

界面有以下方法:

  • keySet() 它以升序返回一组键
  • values() 它以相应键的升序返回所有值的集合

所以这个界面完全符合您的要求.但是,密钥必须具有有意义的顺序.否则,您可以使用LinkedHashMap,其中订单由插入顺序确定.

  • 要使用TreeMap,它需要密钥类必须实现Comparable接口.如果没有,那么将抛出某种RuntimeException.TreeMap它也是排序的地图,但我认为作者想要使用刚刚排序(未排序)的地图.LinkedHashMap是获得仅有序地图的好选择(正如你所说,"由插入顺序决定"). (6认同)
  • 来自 [java 8 doc](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html)。`LinkedHashMap`,其迭代顺序是**上次访问其条目的顺序** (6认同)
  • @TRiNE 我没有关注你的评论,但我可能错过了一些上下文。默认情况下,LinkedHashMap 的迭代顺序是插入顺序,但您可以使用不同的构造函数来指定访问顺序。https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html#LinkedHashMap-int-float-boolean- (4认同)
  • 示例:SortedMap <String,Object> map = new TreeMap <>(); (2认同)

Joh*_*lla 201

是否存在一个像Map一样的对象来存储和访问键/值对,但是可以返回一个有序的键列表和一个有序的值列表,这样键和值列表的顺序相同?

您正在寻找java.util.LinkedHashMap.您将获得Map.Entry <K,V>对的列表,它们总是以相同的顺序迭代.该顺序与放置项目的顺序相同.或者,使用java.util.SortedMap,其中键必须具有自然顺序或由a指定Comparator.

  • 并且只是保存读者仔细检查这个,因为通过测试很难验证,`keySet()`方法有效地返回一个LinkedHashSet,它反映了`put()`调用的顺序.请注意,除非您事先"删除()"键,否则对同一个键重复调用`put()`将不会改变顺序. (13认同)

VoN*_*SoN 20

LinkedHashMap维护键的顺序.

java.util.LinkedHashMap似乎就像普通的HashMap一样工作.

  • @ianaya89 我认为这是一个真正的答案,但它与 [John Feminella's](http://stackoverflow.com/a/663388/1677209) 的答案非常相似! (3认同)
  • 如果您想获得一个有序映射,其中条目按照您将其放入映射中的顺序存储,那么 LinkedHashMap 是正确的答案。如果您想独立于放置顺序对映射中的条目进行排序,那么 SortedMap 是正确的答案。 (2认同)

Bas*_*que 9

太长了;博士

\n

要保持按键排序的顺序,请使用实现/接口Map< Integer , String >的两个类之一:SortedMapNavigableMap

\n\n

\xe2\x80\xa6 或第三方实现。也许在Google GuavaEclipse Collections中(I\xe2\x80\x99ve 未检查)。

\n

如果在单个线程中操作地图,请使用第一个TreeMap. 如果跨线程操作,请使用第二个ConcurrentSkipListMap.

\n

有关详细信息,请参阅下表和以下讨论。

\n

细节

\n

这是我制作的图表,显示了Map与 Java 11 捆绑的十个实现的功能。

\n

NavigableMap界面是SortedMap. 逻辑SortedMap上应该删除,但不能删除,因为某些第三方地图实现可能正在使用接口。

\n

正如您在此表中看到的,只有两个类实现了SortedMap/NavigableMap接口:

\n\n

这两个方法都按自然顺序保存键的排序顺序(compareTo使用Comparablehttps://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ Comparable.html)接口)或通过Comparator您传递的实现。这两个类的区别在于,第二个类ConcurrentSkipListMap线程安全的、高并发的

\n

另请参见下表中的“迭代顺序”列。

\n
    \n
  • 该类按其最初插入的LinkedHashMap顺序返回其条目。
  • \n
  • EnumMap按照定义键的枚举类的顺序返回条目。例如,哪个员工负责一周中的哪一天 ( Map< DayOfWeek , Person >) 的地图使用DayOfWeekJava 中内置的枚举类。该枚举定义为首先是星期一,最后是星期日。因此迭代器中的条目将按该顺序出现。
  • \n
\n

其他六个实现不保证它们报告条目的顺序。

\n

Java 11 中的映射实现表,比较它们的功能

\n


bru*_*nde 7

我认为你从框架中得到的最接近的集合是SortedMap

  • 如果我认为值得失去积分,我会拒绝投票.正如上面的答案所指出的,你的答案缺乏关于LinkedHashMap的正确信息,对SortedMap的一点解释也会很好. (3认同)
  • 我就是这么做的。只是说我可以理解为什么有人会投反对票。 (2认同)

Vit*_*nko 5

您可以利用可以按升序或降序键访问和遍历的NavigableMap接口。该接口旨在取代 SortedMap接口。通常,可导航地图是根据其键的自然顺序或在地图创建时提供的比较器进行排序的。

它有三个最有用的实现:TreeMapImmutableSortedMapConcurrentSkipListMap

TreeMap示例:

TreeMap<String, Integer> users = new TreeMap<String, Integer>();
users.put("Bob", 1);
users.put("Alice", 2);
users.put("John", 3);

for (String key: users.keySet()) {
  System.out.println(key + " (ID = "+ users.get(key) + ")");
}
Run Code Online (Sandbox Code Playgroud)

输出:

Alice (ID = 2)
Bob (ID = 1)
John (ID = 3)
Run Code Online (Sandbox Code Playgroud)