java.util.Set.addAll() 方法中的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2652932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:22:53  来源:igfitidea点击:

Problem in java.util.Set.addAll() method

javaset

提问by Yatendra Goel

I have a java.util.Set<City> citiesand I need to add cities to this set in 2 ways:

我有一个java.util.Set<City> cities,我需要通过两种方式将城市添加到这个集合中:

  • By adding individual city (with the help of cities.add(city)method call)

  • By adding another set of cities to this set (with the help of cities.addAll(anotherCitiesSet)method call)

  • 通过添加单个城市(借助cities.add(city)方法调用)

  • 通过向该集合添加另一组城市(借助cities.addAll(anotherCitiesSet)方法调用)

But the problem in second approach is that i don't know whether there were any duplicate cities in the anotherCitiesSet.

但是第二种方法的问题是我不知道anotherCitiesSet.

I want to do some processing whenever a duplicate entry is tried to be entered in thecitiesset.

每当尝试在cities集合中输入重复条目时,我都想做一些处理。

采纳答案by Amber

Copy the citiesset (to say, citiesCopy), and then call citiesCopy.retainAll(anotherCitiesSet)- the resulting set in citiesCopywill contain the intersection of the two sets, thus allowing you to easily see which cities are duplicated, if any.

复制该cities集合(比如说,citiesCopy),然后调用citiesCopy.retainAll(anotherCitiesSet)- 生成的集合citiesCopy将包含两个集合的交集,从而使您可以轻松查看哪些城市被复制(如果有)。

Alternatively, loop through the second set and manually add each of the elements, checking the return value from add()each time:

或者,循环遍历第二组并手动添加每个元素,检查add()每次的返回值:

for(java.util.Set<City> c : anotherCitiesSet) {
    if(!cities.add(c)) {
        // c was a duplicate, do something?
    }
}

回答by Axarydax

Derive a class from java.util.Set, override addAll if possible (if not, create new method) and there add items one by one, and do your custom processing if you detect a duplicate entry.

从 java.util.Set 派生一个类,如果可能,覆盖 addAll(如果没有,则创建新方法),然后一个一个地添加项目,如果检测到重复条目,则进行自定义处理。

回答by Joachim Sauer

You will need to check for duplicates before you call addAll:

在致电之前,您需要检查重复项addAll

Set<City> cities = getCities();
Set<City> otherCities = getOtherSetOfCities();
Set<City> duplicates = new HashSet<City>(otherCities);
duplicates.retainAll(cities);
// now duplicates contains all City objects that are in otherCities and cities

回答by Dean Povey

Before your cities.addAll()do:

在你cities.addAll()做之前:

Set<City> intersection = new HashSet<City>(cities);
cities.retainAll(anotherCitiesSet);

// Process all the items in the intersection, these are your duplicates
...

cities.addAll(anotherCitiesSet);

回答by I Like to Code

I believe that the most elegant solution is to use an implementation of java.util.Set, e.g. java.util.HashSet. For example, the following code adds all the integers in the set dinto the set c, where duplicates are not added.

我认为,最好的解决方法是使用的实现java.util.Set,例如java.util.HashSet。例如,以下代码将集合中的所有整数添加d到集合中c其中不添加重复项

Code:

代码:

import java.util.HashSet;
import java.util.LinkedList;

import com.google.common.base.Joiner;

public class CollectionsTest {

    public static void main(String[] args) {
        HashSet<Integer> c = new HashSet<>();
        c.add(0);
        c.add(1);
        c.add(2);

        HashSet<Integer> d = new HashSet<>();
        d.add(2);
        d.add(3);

        System.out.println("c = " + Joiner.on(", ").join(c));
        System.out.println("d = " + Joiner.on(", ").join(d));
        c.addAll(d);
        System.out.println("c.addAll(d) = " + Joiner.on(", ").join(c));

    }

}

Output:

输出:

c = 0, 1, 2
d = 2, 3
c.addAll(d) = 0, 1, 2, 3

In order for a HashSetto work correctly for the Cityobjects, the Cityobjections should override the hashCode()and equals()methods. Then the HashSetwill remove duplicates when using addAll()for free!

为了使 aHashSetCity对象正确工作,City反对应该覆盖hashCode()equals()方法。然后免费HashSet使用时将删除重复项addAll()

回答by Peng JL-Zhulin

is your city just String (tho it is object) or it is object containing other stuffs?

你的城市只是字符串(它是对象)还是包含其他东西的对象?

  • if String, then I guess above answers will work.

  • if it is object containing things like : String name, int population, etc... And you only want to compare String name to remove duplicates, then you can use {HashSet} class and override its (HashCode) and (equals) methods.

  • 如果是字符串,那么我猜上面的答案会起作用。

  • 如果它是包含以下内容的对象:字符串名称、整数填充等...并且您只想比较字符串名称以删除重复项,那么您可以使用 {HashSet} 类并覆盖其 (HashCode) 和 (equals) 方法。

because you may have two cities: NYC, and another NYC. containing the same info. but since they are two objects in heap. they will have different HashCode. There say, your HashSet will keep both of them. HashSet checks both HashCode and meaning equals().

因为您可能有两个城市:纽约市和另一个纽约市。包含相同的信息。但因为它们是堆中的两个对象。他们会有不同的HashCode。有说,你的 HashSet 将保留它们。HashSet 检查 HashCode 和含义 equals()。

The solution is to override both methods:

解决方案是覆盖这两种方法:

class City{
  String name; //if you only care city name
  ....
  ....
  public boolean equals(Object myCity){  // override equals(). only look at the name.
    City city2 = (City) myCity;
    return this.getName().equals(city2.getName());  //String itself has a .equal() to compare
  }

  public int HashCode(){  // override HashCode(). 
    return name.hashCode();  //also String itself has a .hashCode() to check equality
  }

  public String getName(){
    return name;
  }

...
...
}