Java 比双重嵌套的ArrayList更高效?
我正在构建一个Java后端组件,它每天处理中等数量的数据。我们有一个POJO,我们称之为Java 比双重嵌套的ArrayList更高效?,java,performance,list,data-structures,hashmap,Java,Performance,List,Data Structures,Hashmap,我正在构建一个Java后端组件,它每天处理中等数量的数据。我们有一个POJO,我们称之为小部件,它有大约10个属性。我的软件必须处理小部件列表组:基本上还有其他进程(完全不同的系统)将它们自己的列表放在一起,然后发送到我的软件。我的软件实际上接收到一个如下所示的包装器POJO: public class Payload { private List<Widget> widgets; // <-- what I want private String guid;
小部件
,它有大约10个属性。我的软件必须处理小部件
列表组:基本上还有其他进程(完全不同的系统)将它们自己的列表
放在一起,然后发送到我的软件。我的软件实际上接收到一个如下所示的包装器POJO:
public class Payload {
private List<Widget> widgets; // <-- what I want
private String guid; // GUID; my software doesn't need this
private boolean fizz; // again, my software doesn't need this
... many other properties that I don't care about
}
这些是我们所需要的唯一操作:将完全不同的列表添加到某个大的“批处理”数据结构中,然后在稍后的时间,检查所有这些操作,并对每个小部件执行操作。该软件运行在一些具有大量内存和处理能力的增强服务器上
所以我问:*ArrayList
是正确的选择,HashMap
还是其他什么。。。为什么呢?哈希映射并不比数组列表更有效或更容易使用。如果在某个时候确实需要通过批的GUID键查找批,则可以证明更改是正确的
哈希映射的效率低于数组列表,因为调整其大小意味着必须重新计算哈希代码,并将数据重新分发到相当随机的内存位置。另一方面,调整数组大小会将内容从旧数组线性复制到新数组,这对CPU缓存更为友好
哈希映射也不容易使用。要访问条目,您必须通过地图的条目集,这打破了传统
所以我问:ArrayList
是正确的选择,HashMap
还是其他什么……为什么
最后,重要的是你的软件解决了它应该解决的问题
HashMap比ArrayList更昂贵,如果不需要通过密钥访问数据,ArrayList可能是最佳选择。
此外,在使用ArrayList时,处理所需编写的代码似乎更简单、更高效
顺便说一句,拥有ArrayList
或HashMap
有点异味。可能您正在建模的是一个ArrayList
,而WidgetGroup
包含一个列表(以及您目前可能不需要的所有其他属性)。但是,如果您的WidgetGroup只包含一个ArrayList,那么不要引入这个新类(让它更简单)
这让我想:谁是对的
在您的解决方案和同行评论员的解决方案之间,我个人非常喜欢您的解决方案
但是,你可以把这个留给自己,并遵循“技术线索”。如果这是他们的角色,那么重要的是他们的决定以及他们提供这些选择的责任。(支付支票的人总是对的)也许你最终想要的是一个嵌入式(核心)数据库。另一种可能是JavaSpaces/NoSQL,即分离交付和处理。视情况而定。有一个名词您一直在使用,但您的数据模型中缺少:Batch。
如果您真的关心将它们保留在批处理中,并保持代码可读性,请将它们封装在批处理类中:
class Batch {
String guid;
List<Widget> widgets;
}
类批{
字符串guid;
列表<Widget>widgets;
}
而且,如果您不关心批次,那么您是否可以将它们全部平铺成一个单一的列表
?从您的问题可以清楚地看出,您正在做这些事情
阅读你的数据
添加更多小部件
问题是,将数据结构从ArrayList更改为HashMap
将如何影响上述两项活动
1)阅读:您已将它们分组为4个组,因此使用hashmap
您将使用哈希存储组,这对于小数据集(您的情况下是组)来说确实没有意义,因此无需在此处使用hashmap
2)添加更多小部件:您将访问要添加到的列表,所以同样的,您也要阅读。使用ArrayListObj.get(index)
不会有什么坏处
现在使用ArrayList
将始终按顺序读取widgets
。使用Hashmap(Hashmap)无法实现这一点,但无论如何,我不认为这是您的问题,或者是吗?:-) 如果您必须随机访问内部列表,那么Hashmap将更加高效,并且对于那些看到嵌套循环时突然进入蜂巢的审阅者来说,使用Hashmap的代码看起来更加优雅。但是,如果您必须遍历并访问每个节点,则不会比^2做得更好。你可以把它们塞进数据库,但这只会增加复杂性。它更优雅,就像hashmap一样。当然,所有这些都假设您有内存同时容纳所有250万个小部件。如果您必须对其进行分页,那么某种DB SQL或NoSQL可能会更好。我觉得您说了很多回答核心问题不需要的东西。试着把它看作是列出事实而不是讲述故事。如果你把所有的事情都放在一起处理,你能不能用一个ArrayList
把小部件添加到你的主列表中?另外,在开始处理之前,您是否需要所有500k集,或者您是否可以处理每个小列表,并只存储结果。生成一个线程来处理每个小列表,然后在完成后抛出该列表可能会大大提高内存效率。请注意,您的用户名让我发笑=)处理顺序重要吗?您想先处理较旧的批次吗?如果是这样,guid键控映射将破坏这种排序(除非您使用树形映射并可以保证guid处于有序状态)@Dukeling我部分同意,但是如果您跳到最后,问题就相当清楚了。可能从“TL”中获益;博士的标题,但我发现额外的上下文对我个人很有帮助。
class Batch {
String guid;
List<Widget> widgets;
}