Java 如何使用映射中的时间戳作为键

Java 如何使用映射中的时间戳作为键,java,hashmap,timestamp,Java,Hashmap,Timestamp,我正在对一个银行应用程序进行编码挑战,在这个应用程序中,我需要在最后60秒内获取交易数量。 为此,我使用java.sql.Timestamp作为map的键,如下所示: Map<Timestamp, List<Transaction>> transactions1 = new HashMap<>(); Map transactions1=newhashmap(); 此处的值是当时完成的事务列表。 我不能使用DB。我知道如何迭代地图并获取数据,但为此,我需要迭

我正在对一个银行应用程序进行编码挑战,在这个应用程序中,我需要在最后60秒内获取交易数量。 为此,我使用
java.sql.Timestamp
作为
map
的键,如下所示:

Map<Timestamp, List<Transaction>> transactions1 = new HashMap<>();
Map transactions1=newhashmap();
此处的值是当时完成的事务列表。 我不能使用DB。我知道如何迭代地图并获取数据,但为此,我需要迭代整个
map
,这将非常耗时

1) 我的问题是
Map
这个问题的数据结构是否正确

2) 如果是这样,我如何减少它(可能是通过
NavigableMap


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

哈希映射只考虑映射(基于哈希代码和等式)

这意味着:您必须
get()
地图的所有关键点,以确保在特定时间间隔内正确识别这些关键点。不可能有快捷方式,始终对地图中的所有键进行完整的O(n)扫描

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

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


意思:低挂果实是简单地从HashMap更改为TreeMap,巧妙地搜索区间边界。但对于“真实世界”场景,您可能需要处理数十万或数百万条条目,这种方法仍然不够。然后,您必须非常仔细地设计一个解决方案,以优化您最重要的需求。但这是只有您才能做到的。

提高性能的一种方法是转储内部
for
循环。通过在
HashMap
中添加
列表
,您必须在另一个循环中使用循环来访问
事务
对象


使用

因此,在迭代时,您立即拥有
事务
对象。如果要获取
时间戳

new Timestamp(nanoseconds/1000000);

为什么不使用epoch timestamp作为键
1534698909
,以便根据键对映射进行排序并获得值呢?我认为
timestamp
是错误的类。第一,它已经过时很久了,第二,它是为SQL数据库设计的。考虑<代码>即时>代码>或其他类。如果您需要的是事务数,那么每次存储该数就足够了(您不需要实际事务列表)。我会考虑一对时间和数字的列表,让列表按时间排序。然后,只需找到最后几分钟内最早的计数,并将该点的数字相加即可。我们对您的需求了解不够,无法判断这是否是一个好的解决方案,这也是我投票结束您的问题的原因。尽管如此,这意味着根据未排序的顺序对地图进行完整的迭代。当然,您的想法使查找速度加快了一点,但它仍然意味着您必须始终查看地图中的所有条目。因为你必须检查每一把钥匙。这意味着你有O(n)。总是将其与排序键进行比较,并能够进行二进制搜索以确定需要考虑的第一个键!但可能存在同时有两个事务的情况。在这种情况下,该值将被覆盖。我知道纳秒不太可能,但很有可能,对吧?@J.Doe是的,有可能。但是它非常罕见,比如100万:1。
System.nanotime()
没有给您一个定义良好的时间点,因此您没有获得有效的时间戳
Instant.now()是一个选项。
System.nanoTime();
new Timestamp(nanoseconds/1000000);