我正在构建一个Java后端组件,每天处理适量的数据。我们有一个POJO,叫做Widget
,它有大约10个属性。我的软件必须处理Widget
列表的组:实际上有其他进程(完全不同的系统)组合他们自己的List<Widget>
,然后将它们发送到我的软件。我的软件实际上接收到一个外壳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
}
我的软件聚合了所有这些由不同系统创建的
List<Widget>
,然后在一个大批次中一起处理它们。为此,我暂时选择了ArrayList<ArrayList<Widget>>
作为保存这个Widget
列表的数据结构。大约会有500,000组List<Widget>
(外部ArrayList
),每个List<Widget>
将包含大约5个Widget
,因此总共有约2.5百万个Widget
在内部ArrayList
中。在最近的代码审查中,一些技术领导告诉我,我选择了错误的数据结构来处理这个批量小部件。他们告诉我,我应该使用
HashMap<String,List<Widget>>
,因为它更有效率和易于使用。哈希映射键是包含在我的软件中的Payload
中的GUID。虽然我没有任何原因需要GUID,但它只是用作保持~500,000个List<Widget>
分开的键——这正是我需要做的。这让我想:到底谁是对的??我们对这个数据结构进行的唯一操作是“添加”(在
ArrayList
的情况下,只需通过add(...)
添加Widget
或List<Widget>
)和“读取”(在我的软件中,我必须遍历每个Widget
并对其进行检查。对于我的嵌套ArrayList
,其要点是:for(List<Widget> widgetList : myDoublyNestedArrayOfWidgets) {
for(Widget widget : widgetList) {
...
}
}
这些是我们需要的唯一操作:将不同的
List<Widget>
添加到一个大的“批处理”数据结构中,然后在稍后检查所有这些数据并对每个Widget
执行操作。 这个软件在一些性能强劲的服务器上运行,具有大量的内存和处理能力。因此,我想问:
ArrayList<ArrayList<Widget>>
、HashMap<String,List<Widget>>
还是其他什么东西是正确的选择,为什么?
ArrayList<Widget>
并随着widget的到来将它们添加到主列表中。此外,您是否需要在开始处理之前先获取全部的50万组数据,或者每次只处理一个小列表并存储结果即可。针对每个小列表生成一个线程以进行处理,并在完成后丢弃该列表,这种做法可能更节省内存。 - Windle