【问题标题】:Fastest option for storing and retrieving objects in a list in Java?在 Java 列表中存储和检索对象的最快选项?
【发布时间】:2021-02-02 19:04:29
【问题描述】:

假设我有一个多人游戏,服务器上有大约 100-1000 名玩家。

考虑以下选项。哪个是存储和检索玩家更快的选择,这种差异是否有意义或可以忽略不计?

选项 1:

List<Player> players = new ArrayList<Player>();

选项 2:

HashMap<String, Integer> usernamesToIds = new HashMap<String, Integer>();
List<Integer> availableIDs = new ArrayList<Integer>;
List<Integer> usedIDs = new ArrayList<Integer>();
Player[] players = new Player[1000];

对于选项 1,任何时候您想通过用户名获取玩家,都必须遍历整个列表直到匹配到一个,而使用选项 2,您可以通过从 HashMap 获取他们的数组索引来立即获取该玩家.

为了遍历第二个数组,我有一个包含所有非空索引的“usedIDs”列表,您可以遍历该列表并从列表中访问数组索引。此外,如果您从列表中删除一个玩家,则使用选项 1 会更改许多其他玩家的 id。

编辑:抱歉,我添加了另一个列表,即“availableIDs”列表。每当添加玩家时,我都会从该列表中删除一个 id 并将其放入“usedIDs”列表中(当玩家被移除时则相反)以继续为玩家分配免费 id。

【问题讨论】:

  • IMO 选项 1,主要是因为它更有条理(也许更快)
  • 对于 1000 个条目,您将无法看到性能差异,尽管 Map 是基于键的查找的一般方法。
  • 为什么不把用户名映射到玩家HashMap&lt;String, Player&gt;
  • 不确定为什么您需要选项 2 中的列表。您的哈希图会将用户名映射到 Player 对象,而不是玩家在某些辅助列表中的索引。作为一般规则,如果您必须反复在列表中搜索相同的项目,那么您做错了。
  • 如果您还想通过 id 获取玩家,那么可能仅使用 hashmap 是不够的。

标签: java arrays arraylist hashmap multiplayer


【解决方案1】:

如果您希望列表中有多达 1000 个项目,并且搜索是偶尔的(例如由用户操作触发)而不是连续的(例如运行游戏的每个“帧”),那么真的不需要做任何事情除了遍历列表。

players.stream().filter(p -> p.getName().equals(searchName)).findFirst();

使用地图的性能提升不值得额外的代码复杂性。将优化重点放在您可以(通过分析器)看到真正的性能瓶颈的区域。

如果您确实需要额外的性能,请避免建议的通过索引进行间接寻址。这非常容易出错(例如,如果您删除了一个玩家,您需要重新索引地图)。而只是从玩家的名字映射到玩家对象。

Map<String,Player> players = new HashMap<>();

这可以作为玩家的主要收藏。您可以使用players.values() 将其用作纯粹的玩家集合。

如果您要存储单独的播放器集合,则需要确保两个存储的完整性:例如确保从两者中添加和删除玩家。所以最好避免,除非你真的需要它。

【讨论】:

    猜你喜欢
    • 2011-12-17
    • 2011-07-22
    • 2012-07-13
    • 2017-03-17
    • 2015-07-01
    • 2020-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多