Java有序映射

Java有序映射,java,collections,Java,Collections,在Java中,是否有一个对象可以像映射一样存储和访问键/值对,但可以返回键的有序列表和值的有序列表,从而使键和值列表的顺序相同 作为代码的解释,我正在寻找一些行为类似于我虚构的OrderedMap的东西: OrderedMap<Integer, String> om = new OrderedMap<>(); om.put(0, "Zero"); om.put(7, "Seven"); String o = om.get(7); // o is "Seven" List

在Java中,是否有一个对象可以像映射一样存储和访问键/值对,但可以返回键的有序列表和值的有序列表,从而使键和值列表的顺序相同

作为代码的解释,我正在寻找一些行为类似于我虚构的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);
}
OrderedMap om=neworderedmap();
om.put(0,“零”);
om.put(7,“七”);
字符串o=om.get(7);//o是“七”
List keys=om.getKeys();
列表值=om.getValues();
对于(int i=0;i
是否有一个对象可以像映射一样存储和访问键/值对,但可以返回键的有序列表和值的有序列表,以便键和值列表的顺序相同


你在找我。您将得到一个成对的列表,它们总是以相同的顺序进行迭代。该顺序与您放置项目的顺序相同。或者,使用,其中键必须具有自然顺序或由
比较器指定。我认为从框架中获得的最接近的集合是接口(带有实现)应该是您的朋友

该接口具有以下方法:

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

因此,该接口完全满足您的需求。但是,键必须具有有意义的顺序。否则,您可以使用插入顺序来确定顺序。

我认为SortedMap接口强制执行您的请求,TreeMap实现了这一点


自Java 6以来,还有非阻塞线程安全的替代方案。 请参阅。

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

它有三个最有用的实现:、和

树映射示例:

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) + ")");
}

LinkedHashMap维护键的顺序


java.util.LinkedHashMap在其他方面的工作方式与普通HashMap类似。

我使用了简单HashMap、链表和集合来按值对映射进行排序

import java.util.*;
import java.util.Map.*;
public class Solution {

    public static void main(String[] args) {
        // create a simple hash map and insert some key-value pairs into it
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("Python", 3);
        map.put("C", 0);
        map.put("JavaScript", 4);
        map.put("C++", 1);
        map.put("Golang", 5);
        map.put("Java", 2);
        // Create a linked list from the above map entries
        List<Entry<String, Integer>> list = new LinkedList<Entry<String, Integer>>(map.entrySet());
        // sort the linked list using Collections.sort()
        Collections.sort(list, new Comparator<Entry<String, Integer>>(){
        @Override
         public int compare(Entry<String, Integer> m1, Entry<String, Integer> m2) {
        return m1.getValue().compareTo(m2.getValue());
        }
      });
      for(Entry<String, Integer> value: list) {
         System.out.println(value);
     }
   }
}
tl;博士 要使
Map
按键排序,请使用实现
SortedMap
/
NavigableMap
接口的两个类之一:

  • TreeMap
  • ConcurrentSkipListMap
如果在单个线程内操作贴图,请使用第一个
TreeMap
。如果跨线程操作,请使用第二个,
ConcurrentSkipListMap

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

细节 下面是我制作的一个图表,显示了与Java11捆绑在一起的十个
Map
实现的特性

接口本来就是应该有的。逻辑上应删除
SortedMap
,但不能删除,因为某些第三方地图实施可能正在使用该接口

如本表所示,只有两个类实现了
SortedMap
/
NavigableMap
接口:

这两种方法都按键的自然顺序(使用
Comparable
()接口的方法)或通过传递的实现来保持键的排序顺序。这两类之间的区别是,第二类,是,高度

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

  • 该类按原始插入的顺序返回其条目
  • 按键的枚举类的定义顺序返回项。例如,一个映射哪个员工正在覆盖一周中的哪一天(
    map
    )使用Java中内置的enum类。该枚举定义为星期一第一个星期日最后一个星期日。因此迭代器中的条目将按该顺序出现
其他六个实现没有承诺报告条目的顺序


Steffi Keran答案的现代Java版本

public class Solution {
    public static void main(String[] args) {
        // create a simple hash map and insert some key-value pairs into it
        Map<String, Integer> map = new HashMap<>();
        map.put("Python", 3);
        map.put("C", 0);
        map.put("JavaScript", 4);
        map.put("C++", 1);
        map.put("Golang", 5);
        map.put("Java", 2);
        // Create a linked list from the above map entries
        List<Map.Entry<String, Integer>> list = new LinkedList<>(map.entrySet());
        // sort the linked list using Collections.sort()
        list.sort(Comparator.comparing(Map.Entry::getValue));
        list.forEach(System.out::println);
    }
}
公共类解决方案{
公共静态void main(字符串[]args){
//创建一个简单的哈希映射,并在其中插入一些键值对
Map Map=newhashmap();
map.put(“Python”,3);
地图放置(“C”,0);
map.put(“JavaScript”,4);
map.put(“C++”,1);
地图.put(“Golang”,5);
map.put(“Java”,2);
//从上述地图条目创建链接列表
List=新的LinkedList(map.entrySet());
//使用Collections.sort()对链表进行排序
排序(Comparator.comparing(Map.Entry::getValue));
list.forEach(System.out::println);
}
}

如果您只想同时遍历这两个对象,那么Map.entrySet()将允许您在任何映射上执行此操作。LinkedHashMap有一个定义良好的顺序,但是对于任何映射,条目集都会反映键/值对。这段代码不是一个很好的示例,因为任何映射实现都将作为示例代码。排序、排序或不排序。在Sun JDK实现中,getKeys和getValues()集合返回的集合由映射中的entrySet()支持,因此将具有相同的迭代顺序,这就是您的示例测试的顺序。这很有趣,我从未注意到这一点。尽管如此,还是说我疯了,但我不喜欢对接口没有明确验证的实现进行假设。我在过去做过很多次这样的事情,这应该被命名为Java排序映射,因为排序映射是
C=0
C++=1
Java=2
Python=3
JavaScript=4
Golang=5
public class Solution {
    public static void main(String[] args) {
        // create a simple hash map and insert some key-value pairs into it
        Map<String, Integer> map = new HashMap<>();
        map.put("Python", 3);
        map.put("C", 0);
        map.put("JavaScript", 4);
        map.put("C++", 1);
        map.put("Golang", 5);
        map.put("Java", 2);
        // Create a linked list from the above map entries
        List<Map.Entry<String, Integer>> list = new LinkedList<>(map.entrySet());
        // sort the linked list using Collections.sort()
        list.sort(Comparator.comparing(Map.Entry::getValue));
        list.forEach(System.out::println);
    }
}