我正在处理银行应用程序上的编码挑战,我需要在最近60秒内获取交易数量。
为此,我使用java.sql.Timestamp
作为map
的键,如下所示:
Map<Timestamp, List<Transaction>> transactions1 = new HashMap<>();
此处的值是当时完成的交易的列表。
我不能使用数据库 。我知道如何遍历地图并获取数据,但为此,我需要遍历整个map
,这将很耗时。
1)我的问题是
Map
是解决此问题的正确数据结构吗?2)如果是,那我该如何减少(可能是
NavigableMap
)?
我不是要编码解决方案,而是要使用正确的设计/数据结构。
答案 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);