我有一个包含两个字符串的Java类,例如一个人的名字和该组的名称。
我还有一个小组列表(大约10个)和一个人员列表(大约100个)。我的数据对象列表较大,可超过10.000项。
现在我想搜索我的数据对象,以便找到所有具有人员列表中的人和组列表中的人的对象。
我的问题是:人员和群组列表的最佳数据结构是什么?
我可以使用ArrayList并简单地迭代直到找到匹配,但这显然效率低下。 HashSet或HashMap会好得多。
有没有更有效的方法来解决这个问题?请指教。
答案 0 :(得分:2)
每个数据结构都有利弊。
如果您有访问密钥,则Map
用于检索O(1)中的数据。
List
用于保存元素之间的顺序,但是不可能使用键访问元素,并且需要循环在O(n)中发生的整个列表。
答案 1 :(得分:1)
用于存储和查找字符串的良好数据结构是Trie:
它本质上是一个树结构,它使用字符或子串来表示要遵循的路径。
哈希映射的优势(引自维基百科):
- 与不完美的哈希表相比,查找trie中的数据在最坏的情况下更快,O(m)时间(其中m是搜索字符串的长度)。不完美的哈希表可能存在关键冲突。密钥冲突是将不同密钥的哈希函数映射到哈希表中的相同位置。不完美哈希表中的最坏情况查找速度是O(N)时间,但更典型的是O(1),花费O(m)时间来评估哈希值。
- trie中没有不同键的冲突。 只有当一个键与多个值相关联时,trie中的桶(类似于存储键冲突的哈希表桶)才是必需的。
- 不需要提供哈希函数或更改哈希函数,因为更多的键被添加到trie中。
- 特里可以按键按字母顺序排列。
答案 2 :(得分:0)
我同意@Davide的回答。如果我们想要快速查找以及维护订单,那么我们可以去实现Map的LinkedHashMap
。
通过使用它,我们可以同时拥有两件事:
数据检索,如果我们有访问密钥。
我们可以维护插入顺序,因此在迭代时我们将按照插入期间的顺序获取数据。
答案 3 :(得分:0)
根据场景(如果您在接收群组/人员列表之前有数据),预处理数据可以节省您的时间。
将数据与群组/人员列表进行比较至少需要10,000多次查找。将组/人员列表与数据进行比较将需要最多$campaigns = Campaign::where('status', '=', 1)->with(['gamemaster' => function($query){
$query->select(['id', 'gamemaster_id', 'name', 'updated_at']);
}]->select('id', 'name')->get()->sortByDesc(function ($campaign) {
return $campaign->gamemaster->updated_at;
})
个查找,如果您一次比较一个组(10*100 = 1,000
查找),则需要更少。{