如何在地图中将时间戳记用作键

时间:2018-08-19 17:11:39

标签: java hashmap timestamp

我正在处理银行应用程序上的编码挑战,我需要在最近60秒内获取交易数量。 为此,我使用java.sql.Timestamp作为map的键,如下所示:

Map<Timestamp, List<Transaction>> transactions1 = new HashMap<>();

此处的值是当时完成的交易的列表。 我不能使用数据库 。我知道如何遍历地图并获取数据,但为此,我需要遍历整个map,这将很耗时。

  

1)我的问题是Map是解决此问题的正确数据结构吗?

     

2)如果是,那我该如何减少(可能是NavigableMap)?

我不是要编码解决方案,而是要使用正确的设计/数据结构。

2 个答案:

答案 0 :(得分:3)

HashMap仅考虑映射(基于哈希码和相等性)。

这意味着:您必须get()地图的所有键,以确保您正确识别出一定间隔内的键。没有捷径可做,总是对地图中的所有键进行一次完整的O(n)扫描。

因此您是正确的:任何有效策略都必须允许您搜索该地图(采用基于数组/随机访问的方法),因此实现NavigableMap的地图(例如TreeMap)成为更好的选择。 TreeMap也经过排序,因此您可以实现“二进制搜索”的某种方式来识别最近n秒内的时间戳。含义:您需要O(log n)来确定时间间隔内的第一个时间戳,然后只要继续获取跟随键,直到达到时间间隔的上限即可。

除此之外,投资于自己的某种 index 实施方式可能会有所帮助。就像一个列表,它记住1/5 / n分钟间隔的第一个时间戳。

含义:悬而未决的结果是,只需从HashMap更改为TreeMap,即可巧妙地搜索间隔边界。但是对于“现实世界”场景,您可能不得不处理成千上万个条目,这种方法仍然不够。然后,您将必须非常仔细地设计一个解决方案,以最重要的要求进行优化。但这是您唯一可以做的事情。

答案 1 :(得分:1)

提高性能的一种方法是转储内部for循环。通过在List<Transaction>中添加HashMap,您将不得不在另一个循环中使用一个循环来访问Transaction对象。


使用

HashMap<Long, Transaction> transactions = new HashMap<>();

并使用纳秒作为密钥。

System.nanoTime();

因此,进行迭代时,您立即拥有Transaction对象。如果您想获取Timestamp

new Timestamp(nanoseconds/1000000);