【问题标题】:How to store a range of int pairs in a map如何在地图中存储一系列整数对
【发布时间】:2017-07-27 07:14:15
【问题描述】:

我有代码,我需要将一系列 y-y 和 z-z 坐标存储为 HashMap 的一个键。

目前,我正在遍历每个 y 和 z 坐标;将它们包装在一个元组中,然后将该元组保存为指定值的键。但是,这对我来说似乎效率不高,因为内存使用可能会成为问题。

假设我的 y 范围在 50-100 之间,z 范围也在 50-100 之间。是否可以存储 y 和 z 范围并作为有效示例 (75,75) 检索映射到范围的值? 101,101 将是一个无效的示例。

最后,我还需要防止密钥对与 x 或 z 重叠。

如果有人可以帮助我解决这个问题,我将不胜感激。

问候

【问题讨论】:

  • 你能举一些键/值对的例子吗?不明白
  • 请给我们一个Minimal, Complete, and Verifiable example。从描述中我不明白你想要做什么
  • @azro 例如,键是new Tuple(new Range(25, 75), new Range(25, 75)),值是任何对象。我希望能够从两个给定整数的键中检索值,这两个整数都在 Tuple 类中的两个值的范围内,而不必使用直接迭代
  • 您使用迭代,因为对于 Map 您需要相等才能从键中取回一个值,实际上给出具有相同范围的相同元组,但这显然不是您不想做的,你想在两个 Range 中都给出 2 个整数,你可以适当的迭代(或 Stream),
  • 迭代的问题是我的性能。

标签: java


【解决方案1】:

您可能正在寻找IntervalTree

我不久前发布了一个示例here

【讨论】:

    【解决方案2】:

    我从你的实现中做了一些假设:

    public class Range {    
        private final int from;    
        private final int to;
    }
    // - - AND - - 
    public class Tuple {    
        private final Range rf;    
        private final Range rt;
    }
    

    我建议添加以下方法:

    // In Range class
    public boolean isValid(int x) {
         return (from <= x) && (x <= to);
    }
    //-----------------------------------------------------------------
    // In Tuple class
    public boolean isValid(int x, int y) {
         return rf.isValid(x) && rf.isValid(y);
    }
    

    还有一个类来管理你的东西:

    public class TupleGestion {   
        private static final Map<Tuple, String> map = new HashMap<>();
    
        private static String getValue(int x, int y) {
    
            return map.get(map.keySet().stream()
                              .filter(key -> key.isValid(x, y)).findAny().orElse(null));
        }
    
        public static void main(String[] args) {
            map.put(new Tuple(new Range(25, 75), new Range(25, 75)), "foo");
    
            System.out.println(getValue(0, 0));    // null
            System.out.println(getValue(50, 0));   // null
            System.out.println(getValue(0, 50));   // null
            System.out.println(getValue(50, 50));  // foo
        }
    
    }
    

    这将读取密钥并找到与您的尝试相对应的密钥,将 2 ints 放入两个范围


    编辑 - 性能:

    • 在地图中添加 6000 个随机元素:&lt;5ms
    • 使用nanoTime() 计算使用getValue() 所需的时间:
      • getValue() 20000 次:100ms&lt; t &lt; 150ms
      • System.out.println(getValue()) 20000 次:850ms&lt; t &lt;1sec

    您询问了大约 3000 个元素和 1000 个 getValue() : &lt;5ms(比 1 秒低 200 倍)

    【讨论】:

    • 是的,这就是我想要的。不过,这会是良好的表现吗?因为我需要在地图中有很多对象时每秒至少运行 1000 次。
    • 地图中有多少对象?我会试着告诉你获得 1000 个值的时间
    • 大约有3000个
    • 我已经编辑过,元素比你要求的多 20 倍,地图中的元素多 2 倍;)
    猜你喜欢
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 2016-10-30
    • 2011-11-24
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 2020-11-01
    相关资源
    最近更新 更多