【问题标题】:removing element from arraylist depending on a custom object property根据自定义对象属性从数组列表中删除元素
【发布时间】:2013-05-17 11:07:30
【问题描述】:

我有一个带有自定义对象的 ArrayList。我想要的是根据自定义对象的名称属性从数组中删除重复项。我试图用 Set person = new TreeSet();但它不起作用。我猜是因为该集合正在比较地址或名称属性以外的其他内容。所以我现在正在尝试使用一个也不删除重复项的迭代器。这就是我得到的;

ArrayList<Person> people = new ArrayList<Person>();
Iterator<Person> iterator = people.iterator();
while (iterator.hasNext()) {
   Person person = iterator.next();

   if (person.getName().equals(iterator.next().getName())) {
       iterator.remove();
   }
}
for (Person person : people) {
    System.out.println(person.getName());
}

虽然我在其中看到重复项,但 ArrayList 并未被修改。我需要帮助。谢谢!

【问题讨论】:

  • 人是否实现了equals和hashcode?如果你实现 equals 和 hashcode,Set 应该可以工作
  • 在迭代时删除通常是个坏主意......也许最好创建一个单独的列表并将预期结果过滤(添加)到新列表中。
  • 为什么在迭代时删除是个坏主意?如果仅从一个线程访问它,这是一个好主意。如果不是,您还有其他问题

标签: java arraylist iterator


【解决方案1】:

您的代码当前已损坏,因为您仅将对象与列表中的下一个对象进行比较。要纠正您当前的方法,您需要有另一个子循环,它将每个对象与列表中的 all 其他对象进行比较。这可能会使嵌套迭代器变得混乱。

另一种方法是定义一个新列表,并在您确认它们不重复后用项目填充它。这避免了嵌套迭代器。

最后,另一种选择是定义一个equals 方法,该方法基于此属性进行比较,并将对象放入Set 中。不要忘记hashCode

【讨论】:

  • 将对象与下一个对象进行比较 此外,下一个对象不会与第三个对象进行比较。第四个对象不会与第五个对象比较 ....
【解决方案2】:

每次编写 .next() 时,迭代都会向前迈出 1 步。因此,假设您的列表中有 10 个人。您选择第一个人,然后使用 iterator.next() 检查下一个人。虽然您获取了第 2 个人,但迭代器现在位于第 2 个人。所以在下一次运行中,第 3 个人被提取并与第 4 个人进行比较。

你应该做的是,选择1个人并将他的名字与列表中所有10个人的名字进行比较,然后从列表中删除所有重复对象的实例。

【讨论】:

    【解决方案3】:

    我有同样的情况,我想出了这个解决方案来使用SortedSet。在这种情况下,那些导致 set 的比较器返回 0 的对象只会在 Set 中插入一次。

    这是一个例子:

    SortedSet<Person> persons = new TreeSet<Person>(new Comparator<Person>() {
        @Override
        public int compare(Person arg0, Person arg1) {
            return arg0.getName().compareTo(arg1.getName());
        }
    });
    

    现在,如果您将Person 插入您的persons,则不会插入重复项(基于它们的name 属性)。

    因此,您可以迭代 list&lt;Person&gt; 并将其中的每个项目插入到您的 persons 集合中,并确保您不会有任何重复项。所以剩下的就是:

    Iterator<Person> iterator = people.iterator();
    while(iterator.hasNext()) {
        persons.add(iterator.next());
    }
    people.clear();
    people.addAll(persons); //Now, your people does not contain duplicate names
    

    【讨论】:

    • 我在我的 Person 类中实现了 ComparableComparator,效果很好。非常感谢
    • 嘿..我已经做到了并且成功了。但是我的带有重复值的原始列表也更改为排序值。不知道为什么。请帮帮我。
    • 最有可能的是,您没有在列表中创建copy,而是将它们直接放入您的sorted-set。这听起来可能有点琐碎,但最好有一个 for-loop 并将每个元素复制到新集合中,以保留您的第一个列表。
    【解决方案4】:

    它不会被删除,因为您只是将每个元素与下一个元素进行比较。您可以将名称存储在一个 HashSet 中,该 HashSet 只能容纳每个字符串中的 1 个,然后如果它的名称已经在集合中,则删除该项目。

    HashSet<String> seen = new HashSet<String>();
    while (iterator.hasNext()) {
         Person p = iterator.next();
         if (seen.contains(p.getName())) {
               iterator.remove();
         } else { 
               seen.add(p.getName());
         }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-02-23
      • 1970-01-01
      • 2018-09-12
      • 1970-01-01
      • 2020-04-28
      • 1970-01-01
      • 2015-12-07
      • 1970-01-01
      相关资源
      最近更新 更多