我应该使用" Set"或"列表"

时间:2016-03-21 03:22:16

标签: java list collections set

我正在学习Java.util.Collection并遇到了以下问题和答案。

  

考虑四个核心接口,Set,List,Queue和Map。对于每一个   在以下四个分配中,指定四个核心中的哪一个   接口是最适合的,并解释如何使用它来实现   分配

     

1)异想天开的玩具公司(WTI)需要记录其所有的名称   雇员。每个月都会随机选择一名员工   这些记录可以获得免费玩具。

本教程提供的答案是

  

使用列表。通过选择0到0之间的数字来选择随机员工   大小() - 1

但我只是想知道不应该使用Set代替List吗?原因员工是独特的个人,我们不希望多次输入同一名员工。我的想法是正确的还是我错过了什么?有没有人有什么建议?在此先感谢您的帮助!

6 个答案:

答案 0 :(得分:3)

  

但我只是想知道不应该使用Set代替List吗?因为员工是独特的个人,我们不希望多次输入同一名员工。

虽然员工是独特的个人,但他们的名字可能并不明显。使用Set可以消除重复,错误地删除具有相同名称的不同员工的姓名。

答案 1 :(得分:3)

列表似乎是更好的选择。可以在固定时间内访问列表中的元素。如果您正在使用ArrayList,那么您可以使用list.get(index)方法直接获取所需的员工。

如果您选择使用Set,那么您将需要迭代该集合,直到找到随机选择的员工。

例如

int size = empHashSet.size();
int employee = new Random().nextInt(size);
int i = 0;
for(Employee emp : empHashSet)
{
    if (i == employee)
        return emp;
    i = i + 1;
}

因此,列表显然似乎是正确的选择。

答案 2 :(得分:2)

  

员工是独特的个人,我们不希望多次输入同一名员工

这是一个很好的想法,但你做的是在问题中没有提供的假设。问题并没有指定名称将被多次输入,因此尝试去除重复输入只会浪费精力。

比重复数据删除更重要的是,你需要从集合中检索一个值,Set没有一个简单的方法可以做到这一点。你可以迭代它们,但这同样浪费。 ArrayList集合(例如{{1}})允许您在固定时间内检索任意元素。

其他答案也提到您不能假设员工有唯一的名称。这通常是一个很好的事情,要记住代表像人一样的事情,但问题显然假设我们有独特的名字,因为你不知道哪个员工被引用从列表中选择了重复的名称。这就是为什么员工通常会在"真实"应用

答案 3 :(得分:2)

列表似乎是一个不错的选择:

创建每个用户的对象,名称可能相同,但其他信息可以不同,从而创建单独的对象。

将这些对象放在arrayList下。

覆盖 hashCode并等于以提供您的比较逻辑。

[例如,您可以使用可变方式来比较对象,可能在年龄上作为可能唯一的成员变量之一或需要唯一的员工ID ,这将解决您的问题重复问题]

现在为什么列表有帮助:

  1. 索引
  2. 您可以通过使用list.contains(object o)检查对象来避免重复(与您的equals和hashCode实现一起)
  3. 选择随机非常简单,因为它只需要Math.random或Random类对象来引用完整列表中的随机整数。

答案 4 :(得分:0)

名称可能包含重复项。你不能在Set中有两个Tom。

答案 5 :(得分:0)

首先:正如对问题的评论中所述,更详细地理解问题可能更有趣。一般来说,使用具体版本的ListSet(如ArrayListHashSet)的问题的答案并不是那么简单。

Lemme详细说明了为什么会出现这种情况和想法:

  • 使用 ArrayList ArrayList是一个很好的解决方案,如果您知道没有将Employee两次添加到List }}。如果您确切知道第二次添加Employee的确切时间,它也可能是一个很好的解决方案。在后一种情况下,您可以使用以下内容检查员工:

    private List<Employee> employees = new ArrayList<>();
    
    public void addEmployee(final Employee employee, final boolean check) {
        if (check) {
             Employee found = employees.stream().filter(e -> e.equals(employee)).findFirst().orElse(null);
             if (found == null) {
                 this.employees.add(employee);
             }
         } else {
             this.employees.add(employee);
         }
    }
    
  • 使用 HashSet :如果一般情况下添加重复项的可能性会更快。访问随机选择的Employee时速度较慢(参见Varun Risbud帖子)。

您不应忘记,在这两种情况下,Employee必须具有equals功能(请参阅例如What issues should be considered when overriding equals and hashCode in Java?)。此外,当使用HashSet时,Employee的实现也需要覆盖'hashCode'。