【问题标题】:How can I access semi-sparse data efficiently in java?如何在 java 中有效地访问半稀疏数据?
【发布时间】:2015-06-17 07:06:47
【问题描述】:

所以我正在处理一个问题,我将一个大型文本文件解析为数据 - 文件的每一行都由具有多个数据字段的 Node 对象表示。

在程序执行期间,这些对象将根据它们的int id字段(在文本文档中指定)被访问多次。

如果每个id 都存在,我只需将它们存储为Node[] 数组,并且想要使用id x 访问节点,我只需使用nodeArray[x]

但是,数据表明id 的大多数值都不存在。对于我当前的数据集,在集合中介于 0 和最大 idID_MAX 之间的 id 中只有大约 40-50% 存在于集合中。

在我看来,我有两个选择:

使用包含许多未填充条目的大 Node[],如

Node[] nodeArray = new Node[ID_MAX];

BufferedReader br = new BufferedReader(new FileReader(file));
String line;

while((line = br.readLine()) != null) {
    Node n = ... // parse line of text into Node object
    nodeArray[n.getID()] = n;
end
br.close();

这将使访问具有特定 id 的节点变得微不足道,但在数据集很大的情况下会使用大量额外空间。

另一种选择是使用较小的 Node[] 数组并使用稀疏的 int[] 数组进行索引:

Node[] nodeArray = new Node[NUM_ROWS];
int[] indexArray = new Int[ID_MAX];

BufferedReader br = new BufferedReader(new FileReader(file));
String line;
int i = 0;

while((line = br.readLine()) != null) {
    Node n = ... // parse line of text into Node object
    nodeArray[i] = n;
    indexArray[n.id] = i;
    i++;
}

两者中的任何一个总体上是否比另一个更好,还是取决于数据的大小和稀疏性? 有没有比这两种方法更好的方法?

【问题讨论】:

  • 你可以使用 Map

标签: java arrays indexing


【解决方案1】:

根据您在此处的描述,您可以使用 HashMap<Integer, Node>HashMap<Long, Node>,具体取决于您拥有的 id 范围。

根据您的其他要求,LinkedHashMapTreeMap 可能是替代品(LinkedHashMap,如果您需要按插入顺序迭代节点,TreeMap,如果您需要它们按某些排序某些标准)。

【讨论】:

  • 如果你需要节点按照插入的顺序排列 -- 你并不真正知道它们是怎样的。我宁愿说“如果你需要按照插入的顺序迭代节点”(如果你需要迭代节点,顺便说一下,这不是地图的标准用例)。除此之外,这正是我要回答的,你打败了我;-)
  • 你也可以补充一下,地图去掉了知道ID_MAX的限制。
  • @Joffrey 你是对的。我已经更新了我的答案以澄清LinkedHashMap
  • 感谢您的回答。地图似乎与我提出的第二个解决方案非常相似(尽管int[] 数组中没有空值)。使用地图是否有很大的开销?作为旁注;节点不会按插入顺序迭代。一般来说,“附近”节点会比远处节点更频繁地被访问,但没有固定的模式。
  • 对于几乎任何应用程序,任何 Map 实现的开销都不会成为问题。我强烈建议为此类事情选择标准库解决方案。从长远来看,这往往会节省大量时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-18
  • 2019-05-26
  • 1970-01-01
  • 2021-04-14
  • 2020-12-07
相关资源
最近更新 更多