1

我是Java的初学者。我有一个方法如下:

 public void time_filter(Long t1, Long t2){
    NavigableMap<Long, Operations_enter> time_map = new TreeMap<Long, Operations_enter>();
    for(int i=0; i< tm.size();i++){
        Operations_enter op = new Operations_enter();
        op.cpuid_enter = cpu.get(i);
        op.func_enter = stt.get(i);
        op.time_enter = tm.get(i);
        op.src_enter = tok.get(i);

        time_map.put(op.time_enter, op);

    }


    for(Map.Entry<Long, Operations_enter> entry: time_map.subMap(t1, true, t2, true).entrySet()){
        Integer time_func = entry.getValue().func_enter;
        System.out.println(" Filtered function numbers corresponding to given time range is" + time_func);

        }

所以就像上面看到的,我实现了一个NavigableMapwith并且我能够使用NavigableMapTreeMap中的方法过滤给定的范围。subMap但是我现在有一个问题,time_enter包含一些重复的键,所以当我使用时TreeMap,这些值会被最新添加的重复值覆盖。我明白这是如何TreeMap工作的。我也试过使用ConcurrentSkipListMap,但结果是一样的。

ConcurrentSkipListMap和之间的实际区别是什么TreeMap??是否有可能NavigableMap使用TreeMapor来实现,ConcurrentSkipListMap同时在 ? 中包含重复值NavigableMap

编辑 代码现在看起来像这样:

  NavigableMap<Long, Operations_enter> time_map = new TreeMap<Long, Operations_enter>(new Comparator<Long>() {
        public int compare(Long o1, Long o2) {
            return o1.equals(o2) ? 1 : o1.compareTo(o2);
        }
    });
    for(int i=0; i< tm.size();i++){
        Operations_enter op = new Operations_enter();
        op.cpuid_enter = cpu.get(i);
        op.func_enter = stt.get(i);
        op.time_enter = tm.get(i);
        op.src_enter = tok.get(i);

        time_map.put(op.time_enter, op);

    }

    for(Map.Entry<Long, Operations_enter> entry: time_map.subMap(t1, true, t2, true).entrySet()){

       Integer time_func = entry.getValue().func_enter;
        System.out.println(" Filtered function numbers corresponding to given time range is" + time_func);
     }
4

4 回答 4

5

ConcurrentSkipListMapTreeMap都是NavigableMap实现。实现该接口意味着他们将密钥按排序顺序保存。这是他们的共同点。在其他方面,它们完全不同。

是否可以将 NavigableMap 与重复键的映射结构一起使用?

不,TreeMapConcurrentSkipListMap不能处理重复的键。执行 aput时,现有键的先前值替换为到达值。

treemap 和 concurrentskiplistmap 的区别?

3 个区别:空值、性能和并发性。

空值

  • ATreeMap 允许空值,而键必须是非空的。
  • AConcurrentSkipListMap 禁止键或值中的空值。

表现

AConcurrentSkipListMap使用跳表技术。此类可能会显示非常快的搜索性能,同时仍允许快速插入。

跳过列表是可扩展的,即使在进行插入时也能保持大量条目的性能。

并发

正如其他人指出的那样, aConcurrentSkipListMap并发线程安全的。ATreeMap不是。

结论

  • 如果您有大量条目,请使用ConcurrentSkipListMap而不是TreeMap.
  • 如果您要NavigableMap跨线程访问,请使用ConcurrentSkipListMap, never TreeMap
  • 对于在单个线程中访问的条目数量较少,请使用TreeMap.

这是一个总结各种Map实现的表格。单击/点击以缩放。

一个描述 Java 11 中各种 Map 实现方面的表格。

于 2019-10-26T20:01:35.023 回答
3

ConcurrentSkipListMap 是一个 NavigableMap 实现,旨在安全地从多个线程同时使用。这是它与 TreeMap 的主要区别。由于你time_map是一个局部变量,它只能从当前线程访问,你不需要 ConcurrentSkipListMap。

如果您需要一个允许重复键的 TreeMap,您可以尝试制作一个从不返回 0 的自定义比较器:

TreeMap<Integer, Object> m = new TreeMap<>(new Comparator<Integer>() {
    public int compare(Integer o1, Integer o2) {
        return o1.equals(o2) ? 1 : o1.compareTo(o2);
    }
});
m.put(0, 0);
m.put(1, 1);
m.put(1, 1);
m.put(1, 1);
m.put(2, 2);
m.put(3, 3);
m.put(4, 4);
System.out.println(m.subMap(0, false, 3, true));

输出

{1=1, 1=1, 2=2, 3=3}

请注意,它破坏了可能导致意外行为的 Map 合同,例如 m.containsKey(1) 返回 false 而您需要使用 m.subMap(0, false, 2, false) != null

于 2013-06-19T11:29:38.673 回答
0

映射只允许给定键的一个值。你需要的是一个Multimap。JDK 本身不包含 Multimap 的实现(“因为根据http://docs.oracle.com/javase/tutorial/collections/interfaces/map.html,“因为它们并不常用” )。

在 Google Guava 或 Apache Commons Collections 等一些库中有 Multimap 的实现。

在http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/TreeMultimap.html看看 Guava 的 TreeMultimap

于 2013-06-19T11:29:48.070 回答
0

您可以使用作为目标容器 Map<K, List<V>> 来实现 Multimap<K,V> 的功能

于 2018-10-18T21:51:14.407 回答