【问题标题】:Data structure to represent Teams and Players代表球队和球员的数据结构
【发布时间】:2016-09-27 18:05:18
【问题描述】:

有一个Team 对象,其中包含玩家列表List<Players>。所有团队都需要存储在Teams 集合中。

条件:

  1. 如果需要将新玩家添加到特定团队,则从Teams检索该特定团队,并且需要将Player添加到该团队的Players列表中

    李>
  2. 集合Teams中的每个Team对象都需要基于team name是唯一的

  3. 集合中的Team对象需要根据team name进行排序。

注意事项:

在这种情况下,当我使用 List<Team> 时,我可以实现 1, 3 。但不能满足唯一性。

如果我用TreeSet<Team> 2,3就可以实现。但由于 TreeSet 上没有 get 方法,因此无法选择特定团队

所以我最终使用了TreeMap<teamName,Team>。这使得所有 1,2,3 成为可能。但我认为这不是这样做的好方法

哪种数据结构最适合这个用例?最好形成 Java 集合。

【问题讨论】:

  • 为什么不是一个 TreeMap 玩家 -> 团队和一个 TreeSet 团队 -> 玩家?通常将多个简单的数据结构放在一起更有效。构建一个额外的类来保存这些,并提供一个接口来连贯地改变这些。
  • But I think it's not the good way to do it 为什么?
  • TreeMap 对于这个用例来说听起来不错。你为什么不喜欢它?
  • 我的想法是,当我想对这个 TreeMap 进行操作时,我需要同时插入 team nameTeam
  • 唯一性可以满足 List 的要求,方法是覆盖 equals() 以根据团队名称进行评估,然后在插入之前使用 contains。此外,您可以在您的类中创建一个方法 get(String teamName) 来搜索列表。

标签: java algorithm data-structures


【解决方案1】:

如果您愿意,可以使用您的 TreeSet。但是,如果您要使用 Set 接口,您可以使用 remove(object o) 而不是 get。您将移除对象,进行修改,然后将其添加回集合中。

【讨论】:

    【解决方案2】:

    我认为扩展(即从)ArrayList 或 LinkedList 并覆盖 set()、add()、addAll()、remove() 和 removeRange() 方法以确保唯一性和排序条件(不变量)将是一个非常干净的设计。你也可以在你的类中实现一个二分搜索方法来快速找到一个给定名字的团队。

    如果您不打算太频繁地添加或删除团队,ArrayList 是您的课程基础的更好选择。 ArrayList 将为您提供 O(n) 的插入和删除,但如果您使用二分搜索(其中 n 是数组中的元素数),则元素访问和确保唯一性的成本为 O(log n)。

    查看generics tutorial 了解泛型的子类化。

    【讨论】:

      【解决方案3】:

      使用 Guava 的 MultiMap 怎么样?更准确地说,是SetMultimap。具体来说,SortedSetMultimap。更具体地说,它的 TreeMultimap 实现 (1)。

      解释:

      • MultiMap 中,Key 不指向单个值,而是指向Collection 值。
        这意味着您可以将多个 Player 值的集合绑定到单个 Team 键,因此 Req1 已解决。
      • SetMultiMap 中,Keys 是唯一的。
        这可以解决您的 Req2
      • SortedSetMultimap 中,Valuess 也被排序。
        虽然您并不特别关心这个,但很高兴拥有。
      • TreeMultimap 中,Keyset 它们的每个 Values 集合都已排序。
        这会让你的 Req3 排序(看看我在那里做了什么?)

      用法:

      TreeMultimap<Team, Player> ownership = new TreeMultimap<Team, Player>();
      ownership.put(team1, playerA);
      ownership.put(team1, playerB);
      ownership.put(team2, playerC);
      Collection<Player> playersOfTeamA = ownership.get(team1); // contains playerA, playerB
      SortedSet<Team> allTeams = ownership.keySet(); // contains team1, team2
      

      哥达:

      • 记得在Team 对象上正确设置equalshashCode 以使用其name
        或者,如果您不希望更改 Team 的自然排序,您可以使用静态的 create(Comparator&lt;? super K&gt; keyComparator, Comparator&lt;? super V&gt; valueComparator),它提供了一个专门构建的比较。 (使用 Ordering.natural() 作为 Player 比较器以保持其自然顺序 - 另一个不错的 Guava 东西)。无论如何,请确保它与equals兼容!
      • MultiMaps 不是 Maps,因为 put向键添加新值不会删除以前保存的值(这就是重点),因此请确保您理解它。 (例如,它仍然认为您不能两次放置一个键值对......)

      (1): 我不确定 SortedSetMultimap 是否足够。在其 Javadoc 中,它声明值已排序,但没有提及键。有人知道吗?

      (2) 我向你保证,我与 Guava 没有任何关系。我只是觉得太棒了!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-12-07
        • 1970-01-01
        • 1970-01-01
        • 2011-06-22
        • 1970-01-01
        • 1970-01-01
        • 2011-08-02
        相关资源
        最近更新 更多