我可以使用Set集合来消除两个不同的重复吗?

时间:2016-08-26 13:09:39

标签: java collections set equals

我有一个Java项目。首先,我需要在object&的名称中创建一个没有重复的集合。它的编号,所以我使用Set集合和等于方法:

<Response>
    <Dial callerId="[your_twilio_phone_number]">[target_phone_number]</Dial>
</Response>

下一个..我需要创建相同对象的集合,但现在我需要确保只有他的名字不重复。所以这是一个问题因为我不能使用两种不同的equals方法 我该怎么办?

4 个答案:

答案 0 :(得分:2)

我改为使用TreeSet并指定比较器用于该特定集,而不是覆盖equals

https://docs.oracle.com/javase/8/docs/api/java/util/TreeSet.html#TreeSet-java.util.Comparator-

如果您不希望它们实际排序,但只是删除欺骗,比较器只有在相等时才返回0.

TreeSet<Course> tree1 = new TreeSet<Course>((c1, c2) -> c1.number==c2.number && c1.Name.equals(c2.Name) ? 0 : 1);

TreeSet<Course> tree2 = new TreeSet<Course>((c1, c2) -> c1.Name.equals(c2.Name) ? 0 : 1);

答案 1 :(得分:1)

您可以将您的类包装在一个包装类中,该类将以您希望的方式实现hashcodeequals函数:

public NameWrapper {
    private Course c;

    public NameWrapper(Course c) {
        this.c = c;
    }

    public void equals(Object other) {
        // ...
        return this.name.equals(other.name);
    }

    // + hashCode
    // + getter
}

// Similarly with number and name wrapper

然后你可以包装,分开和展开你的元素:

Collection<Course> courses = // ...
Collection<Course> distincts = 
    courses.stream()
           .map(NameWrapper::new)             // wrap
           .distinct()
           .map(NameWrapper::getCourse)       // unwrap
           .map(NumberNameWrapper::new)       // wrap
           .distinct()
           .map(NumberNameWrapper::getCourse) // unwrap
           .collect(Collectors.toList())

答案 2 :(得分:0)

一个简单但可能不是很好的解决方案是使用两个特定的包装类,每个包含不同的等于方法。

而不是直接使用自己的类,而是将这些“包装”类的对象放入这些集合中。

像:

class Course { ... your class

class CourseWrapperForName {
   Course wrappedCourse; 
...
   Course getWrappedCourse() { return wrappedCourse; }
   @Override 
   public boolean equals(Object other) {
   ... compares names

class CourseWrapperForNumber {
   Course wrappedCourse; 
...
   @Override 
   public boolean equals(Object other) {
   ... compares numbers

现在,可以通过将Course对象放入相应的包装器来消除重复;将包装器添加到集合;然后检索课程。

但显然,这是很多样板;更合理的解决方案可能是

A)使用具有不同

的TreeSet B)后来可以用很多黑色lambda魔法增强;有一个很好的presentation怎么做(它是德语,但主要是代码;有趣的部分从第40页开始)。

答案 3 :(得分:0)

我会使用这个equals方法实现Set<Course>(这将给我一个名称和数字都是唯一的路线)。

此外,我会创建课程'SubCourse'的子类并覆盖equals方法:

class SubCourse extends Course{
    public boolean equals(Object o){
                if(o instanceof SubCourse){
                    return (this.Name.equals(((SubCourse)o).Name));
                }else{
                    return false;
                }
        }

    }    

然后制作一个Set<SubCourse>,它将为您提供数字方面的独特课程(不包括我们排除该条件的名称)。您需要将Course的实例变量设为protected