2016-08-26 3 views
0

私はJavaでプロジェクトを持っています。まず、私はその数&オブジェクトの名前で重複なしでコレクションを作成する必要があるので、私はセットのコレクションを使用して、このメソッドと等しい:Setコレクションを使用して、2つの異なるイコールで重複を排除できますか?

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

次..私は、同じオブジェクトのコレクションを作成する必要がありますが、今私は彼の名前だけが重複していないことを保証する必要があります。だから問題は私は2つの異なる方法を使用することはできません 私は何ができますか?

答えて

0

簡単ではあるが、おそらく実際には素晴らしい解決策は、とは異なるというメソッドを持つ2つの特定のラッパークラスを使用することです。

あなた自身のクラスを直接使用する代わりに、それらの "ラッパー"クラスのオブジェクトをそれらのコレクションに入れます。

同様:今

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 

、排除重複が対応するラッパーにあなたのコースのオブジェクトを置くことによって行うことができます。セットにラッパーを追加する。コースを取得します。

しかし明らかに、それは多くの定型文です。より合理的な解決策は、後で黒ラムダ魔法の多くの向上を図ることができる)異なる

BとTreeSetの使用)

Aとすることができます。素敵なことがあります(それはドイツ語ですが、主にコードです;面白い部分は40ページから始まります)。

2

代わりにTreeSetを使用し、equalsを上書きする代わりにその特定のセットに使用するコンパレータを指定します。あなたは彼らが実際にソートしたいのですが、ちょうどdupesを削除しない場合は

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はセットです。 2つのオブジェクトが等しいと比較された場合(つまり、コンパレータが0を返した場合)、新しい値は重複しているとみなされ、除外されます。コンパレータがゼロ以外を返す場合、それらは重複しないで、両方がセットに入ります。したがって、通常はソートに使用されますが、この場合は重複を検出するために使用できます – mprivat

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()) 
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とする必要があります。

関連する問題