2016-08-26 2 views
0

У меня есть проект на Java. Сначала нужно создать коллекцию без каких-либо дубликатов в имени объекта & его номер, поэтому я использую коллекцию Set, и это составляет метод:Могу ли я использовать Set collection для устранения дубликатов на два разных значения?

public boolean equals(Object obj) { 
    Course<?> c=(Course<?>)obj; 
    return (c.number==number&& c.Name.equals(Name)); 
} 

следующих .иХ необходимо создать коллекцию одного и тот же объект, но теперь мне нужно гарантировать, что только его имя не дублируется. поэтому его проблема, потому что я не могу использовать два метода diffrents равных , что я могу сделать?

ответ

0

Одно простое, но, вероятно, не очень хорошее решение заключается в использовании двух конкретных классов-оболочек, каждый из которых имеет разные методы equals.

И вместо прямого использования вашего собственного класса вы помещаете объекты этих классов «обертки» в эти коллекции.

Как:

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 

Теперь, устраняющие дубликаты можно сделать, разместив объекты курса в соответствующей обертку; добавление оберток к наборам; а затем извлечение курса.

Но, очевидно, это много шаблонов; и более разумные решения могут быть

А) с использованием TreeSet с другим

В) позже может быть повышена с большим количеством черной магии лямбда; есть хороший presentation, как это сделать (это по-немецки, но в основном код, интересная часть начинается со страницы 40).

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); 
+0

, но компаратор возвращает int для сравнения не с дублирующими игнорирующими ... только сортирует объекты в деревьях по значению, возвращаемому в некотором порядке, я выбираю .. не так ли? – dan

+0

Набор TreeSet - это набор. Если два объекта сравниваются как равные (т. Е. Компаратор возвращает 0), то новое значение будет считаться дублирующимся и исключенным. Если компаратор возвращает ничего, кроме нуля, они не будут дубликатов, и оба будут в наборе. Так что да, обычно он используется для сортировки, но в этом случае вы можете использовать его для обнаружения дубликатов – mprivat

1

Вы можете обернуть свой класс в класс-оболочку, которая будет осуществлять hashcode и equals Функционирует так, как вы хотите:

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()) 
0

Я бы взял 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.

Смежные вопросы