我必须在内存中保留数千个字符串,以便在Java中串行访问。我应该把它们存储在数组中还是应该使用某种列表?

由于数组将所有数据保存在一个连续的内存块中(与list不同),使用数组存储数千个字符串会导致问题吗?


当前回答

数组-当我们必须实现更快的结果获取时,它总是更好的

列表——执行插入和删除的结果,因为它们可以在O(1)中完成,这也提供了方便地添加、获取和删除数据的方法。更容易使用。

但是始终记住,当数据存储在数组中的索引位置是已知的时,数据的抓取将是快速的。

这可以通过对数组排序很好地实现。因此,这增加了获取数据的时间(即;存储数据+排序数据+寻找数据所在的位置)。因此,这增加了从数组中获取数据的额外延迟,即使它们可能擅长更快地获取数据。

因此,这可以用三元数据结构或三元数据结构来解决。如上所述,树数据结构在搜索数据时非常有效,对特定单词的搜索可以在O(1)量级上完成。当时间紧迫时;如果你必须快速搜索和检索数据,你可以使用三种数据结构。

如果你希望你的内存空间消耗更少,你希望有一个更好的性能,那么使用三元数据结构。这两个都适合存储大量的字符串(例如;比如字典里的单词)。

其他回答

首先,有必要澄清一下,您是指经典的compp sci数据结构意义上的“列表”(即链表),还是指java.util.List?如果你指的是java.util。List,它是一个接口。如果你想使用数组,只要使用数组列表实现,你就会得到类似数组的行为和语义。问题解决了。

如果你指的是数组和链表,这是一个稍微不同的参数,我们回到大O(如果这是一个不熟悉的术语,这里有一个简单的英语解释。

数组;

随机存取:O(1); 插入:O (n); 删除:O (n)。

链表:

随机存取:O(n); 插入:O (1); 删除:O(1)。

你可以选择最适合调整数组大小的方法。如果你调整大小,插入和删除很多,那么链表可能是一个更好的选择。如果随机访问很少,情况也是如此。你提到了串行访问。如果你主要做串行访问,很少修改,那么你选择哪一个可能都不重要。

链表的开销略高,因为正如您所说,您正在处理潜在的不连续内存块和(有效地)指向下一个元素的指针。但是,除非您要处理数百万个条目,否则这可能不是一个重要因素。

列表比数组慢。如果需要效率,请使用数组。如果你需要灵活性,使用列表。

如果你有几千个,考虑使用trie。trie是一种树状结构,它合并了存储字符串的公共前缀。

例如,如果字符串是

intern
international
internationalize
internet
internets

该树将存储:

intern
 -> \0
 international
 -> \0
 -> ize\0
 net
 ->\0
 ->s\0

字符串需要57个字符(包括空结束符'\0')来存储,再加上存储它们的String对象的大小。(事实上,我们可能应该四舍五入到16的倍数,但是……)粗略地称它为57 + 5 = 62字节。

这个trie需要29个存储空间(包括空结束符'\0'),加上对trie节点的sizeof,这些节点是一个数组的引用和一列子trie节点。

在这个例子中,结果可能是一样的;对于成千上万的人来说,只要你有共同的前缀,它可能会更少。

现在,在其他代码中使用trie时,必须转换为String,可能使用StringBuffer作为中介。如果在trie之外,同时使用了许多字符串作为字符串,这是一种损失。

但如果你一次只使用几个——比如,在字典中查找东西——trie可以为你节省很多空间。绝对比存储在HashSet中的空间要小。

你说你是“连续地”访问它们——如果这意味着按字母顺序访问,如果你深度优先迭代,trie显然也会免费给你字母顺序。

这取决于你如何访问它。

存储后,如果你主要想做搜索操作,很少或不需要插入/删除,那么就去数组(因为在数组中搜索是在O(1)中完成的,而添加/删除可能需要重新排序元素)。

存储之后,如果你的主要目的是添加/删除字符串,很少或没有搜索操作,那么就去List。

不,因为从技术上讲,数组只存储对字符串的引用。字符串本身被分配到不同的位置。对于上千个项目,我会说列表会更好,它更慢,但它提供了更多的灵活性,更容易使用,特别是如果你要调整它们的大小。