QA@IT
«回答へ戻る

テストをhamcrestで書き直しました。

5599
 ```java
 package qait9842;
 
-import static org.junit.Assert.*;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.*;
 
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
             this.setName("b");
         }};
 
-        assertEquals(a, b);
-        assertNotEquals(a, "a");
-        assertNotEquals(a, new Bean());
-        assertNotEquals(a, new Bean(){{
+        // 行数節約のため複数ケース書いてます。
+        assertThat(b, is(a));
+        assertThat(new Bean(), is(a));
+        assertThat(new Bean(){{
             setAge(0);
             setId("a");
             setName(null);
-        }});
+        }}, is(a));
     }
 
     @Test
     public void testMakeUniqueWithAddAllMethod(){
-        List<Bean> beans = new LinkiedList<>();
+
+        List<Bean> beans = new LinkedList<>();
         beans.add(new Bean(){{
             setAge(0); setId("a"); setName("b");
         }});
             setAge(0); setId("a"); setName("b");
         }});
 
-        assertEquals(6, beans.size());
 
+        assertThat(beans.size(), is(6));
+
         Set<Bean> work = new LinkedHashSet<>();
         work.addAll(beans);
+
         beans.clear();
         beans.addAll(work);
 
-        assertEquals(2, beans.size());
-        assertEquals("b", beans.get(0).getName());
-        assertEquals("c", beans.get(1).getName());
+        assertThat(beans.size(), is(2));
+        assertThat(beans.get(0).getName(), is("b"));
+        assertThat(beans.get(1).getName(), is("c"));
+
     }
 
     @Test
         beans.clear();
         beans.addAll(work);
 
-        assertEquals(3, beans.size());
-        assertEquals("1", beans.get(0).getId());
-        assertEquals("2", beans.get(1).getId());
-        assertEquals("pojo", beans.get(2).getName());
+        assertThat(beans.size(), is(3));
+        assertThat(beans.get(0).getId(), is("1"));
+        assertThat(beans.get(1).getId(), is("2"));
+        assertThat(beans.get(2).getName(), is("pojo"));
 
     }}
-}
 ```
 
 ダイアモンド演算子つかってるので 1.7以降だろうということで、java1.7でコンパイルしてます。

Beanでequalsとhashcodeをオーバーライドすれば可能です。
ただし、何をもって等しいとするかは設計次第ですので用途に合わせて適切に実装する必要があります。

示された Beanの場合は以下のような感じでしょうか。前述の通り等価とみなす仕様次第なのでそのまま使えるかはわかりません。
(コンストラクタに渡しているageの値がStringなのがちょっとひっかかりますが。)

package qait9842;

public class Bean {
    private String id;
    private String name;
    private Integer age;

    @Override
    public boolean equals(Object obj){

        if (obj==null) return false;

        if (! (obj instanceof Bean) ) return false;
        if (this==obj) return true;

        Bean other = (Bean)obj;
        if(age != other.age) return false;
        if(id == null && other.id != null || id != null && other.id == null) return false;
        if(name == null && other.name != null || name != null && other.name == null ) return false;

        if(age == other.age && id.equals(other.id) && name.equals(name)) return true;

        return false;
    }

    @Override
    public int hashCode() {
        final int oddPrime = 31;
        int result = oddPrime;
        result += age;
        result *= oddPrime;
        result += (name == null) ? 0 : name.hashCode();
        result *= oddPrime;
        result += (id == null) ? 0 : id.hashCode();
        return result;
    }

// constructor
// getter, setter
}

適当ですけどこんなテストはパスします。

package qait9842;

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;

import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.junit.Test;

public class BeanTest {

    @Test
    public void testEqualsObject() {
        Bean a = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        Bean b = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        // 行数節約のため複数ケース書いてます。
        assertThat(b, is(a));
        assertThat(new Bean(), is(a));
        assertThat(new Bean(){{
            setAge(0);
            setId("a");
            setName(null);
        }}, is(a));
    }

    @Test
    public void testMakeUniqueWithAddAllMethod(){

        List<Bean> beans = new LinkedList<>();
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});


        assertThat(beans.size(), is(6));

        Set<Bean> work = new LinkedHashSet<>();
        work.addAll(beans);

        beans.clear();
        beans.addAll(work);

        assertThat(beans.size(), is(2));
        assertThat(beans.get(0).getName(), is("b"));
        assertThat(beans.get(1).getName(), is("c"));

    }

    @Test
    public void testQ9842(){

        List<Bean> beans = new LinkedList<>();
        beans.add(new Bean(){{
            setId("1"); setName("hoge"); setAge(23);
        }});
        beans.add(new Bean(){{
            setId("2"); setName("hoge"); setAge(23);
        }});
        beans.add(new Bean(){{
            setId("3"); setName("pojo"); setAge(24);
        }});
        beans.add(new Bean(){{
            setId("1"); setName("hoge"); setAge(23);
        }});

        Set<Bean> work = new LinkedHashSet<>();
        work.addAll(beans);

        beans.clear();
        beans.addAll(work);

        assertThat(beans.size(), is(3));
        assertThat(beans.get(0).getId(), is("1"));
        assertThat(beans.get(1).getId(), is("2"));
        assertThat(beans.get(2).getName(), is("pojo"));

    }}

ダイアモンド演算子つかってるので 1.7以降だろうということで、java1.7でコンパイルしてます。
junitは4です。

Beanでequalsとhashcodeをオーバーライドすれば可能です。
ただし、何をもって等しいとするかは設計次第ですので用途に合わせて適切に実装する必要があります。

示された Beanの場合は以下のような感じでしょうか。前述の通り等価とみなす仕様次第なのでそのまま使えるかはわかりません。
(コンストラクタに渡しているageの値がStringなのがちょっとひっかかりますが。)

```java
package qait9842;

public class Bean {
    private String id;
    private String name;
    private Integer age;

    @Override
    public boolean equals(Object obj){

        if (obj==null) return false;

        if (! (obj instanceof Bean) ) return false;
        if (this==obj) return true;

        Bean other = (Bean)obj;
        if(age != other.age) return false;
        if(id == null && other.id != null || id != null && other.id == null) return false;
        if(name == null && other.name != null || name != null && other.name == null ) return false;

        if(age == other.age && id.equals(other.id) && name.equals(name)) return true;

        return false;
    }

    @Override
    public int hashCode() {
        final int oddPrime = 31;
        int result = oddPrime;
        result += age;
        result *= oddPrime;
        result += (name == null) ? 0 : name.hashCode();
        result *= oddPrime;
        result += (id == null) ? 0 : id.hashCode();
        return result;
    }

// constructor
// getter, setter
}
```

適当ですけどこんなテストはパスします。

```java
package qait9842;

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;

import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.junit.Test;

public class BeanTest {

    @Test
    public void testEqualsObject() {
        Bean a = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        Bean b = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        // 行数節約のため複数ケース書いてます。
        assertThat(b, is(a));
        assertThat(new Bean(), is(a));
        assertThat(new Bean(){{
            setAge(0);
            setId("a");
            setName(null);
        }}, is(a));
    }

    @Test
    public void testMakeUniqueWithAddAllMethod(){

        List<Bean> beans = new LinkedList<>();
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});


        assertThat(beans.size(), is(6));

        Set<Bean> work = new LinkedHashSet<>();
        work.addAll(beans);

        beans.clear();
        beans.addAll(work);

        assertThat(beans.size(), is(2));
        assertThat(beans.get(0).getName(), is("b"));
        assertThat(beans.get(1).getName(), is("c"));

    }

    @Test
    public void testQ9842(){

        List<Bean> beans = new LinkedList<>();
        beans.add(new Bean(){{
            setId("1"); setName("hoge"); setAge(23);
        }});
        beans.add(new Bean(){{
            setId("2"); setName("hoge"); setAge(23);
        }});
        beans.add(new Bean(){{
            setId("3"); setName("pojo"); setAge(24);
        }});
        beans.add(new Bean(){{
            setId("1"); setName("hoge"); setAge(23);
        }});

        Set<Bean> work = new LinkedHashSet<>();
        work.addAll(beans);

        beans.clear();
        beans.addAll(work);

        assertThat(beans.size(), is(3));
        assertThat(beans.get(0).getId(), is("1"));
        assertThat(beans.get(1).getId(), is("2"));
        assertThat(beans.get(2).getName(), is("pojo"));

    }}
```

ダイアモンド演算子つかってるので 1.7以降だろうということで、java1.7でコンパイルしてます。
junitは4です。

import文の修正

5599
 
 import static org.junit.Assert.*;
 
-import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 

Beanでequalsとhashcodeをオーバーライドすれば可能です。
ただし、何をもって等しいとするかは設計次第ですので用途に合わせて適切に実装する必要があります。

示された Beanの場合は以下のような感じでしょうか。前述の通り等価とみなす仕様次第なのでそのまま使えるかはわかりません。
(コンストラクタに渡しているageの値がStringなのがちょっとひっかかりますが。)

package qait9842;

public class Bean {
    private String id;
    private String name;
    private Integer age;

    @Override
    public boolean equals(Object obj){

        if (obj==null) return false;

        if (! (obj instanceof Bean) ) return false;
        if (this==obj) return true;

        Bean other = (Bean)obj;
        if(age != other.age) return false;
        if(id == null && other.id != null || id != null && other.id == null) return false;
        if(name == null && other.name != null || name != null && other.name == null ) return false;

        if(age == other.age && id.equals(other.id) && name.equals(name)) return true;

        return false;
    }

    @Override
    public int hashCode() {
        final int oddPrime = 31;
        int result = oddPrime;
        result += age;
        result *= oddPrime;
        result += (name == null) ? 0 : name.hashCode();
        result *= oddPrime;
        result += (id == null) ? 0 : id.hashCode();
        return result;
    }

// constructor
// getter, setter
}

適当ですけどこんなテストはパスします。

package qait9842;

import static org.junit.Assert.*;

import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.junit.Test;

public class BeanTest {

    @Test
    public void testEqualsObject() {
        Bean a = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        Bean b = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        assertEquals(a, b);
        assertNotEquals(a, "a");
        assertNotEquals(a, new Bean());
        assertNotEquals(a, new Bean(){{
            setAge(0);
            setId("a");
            setName(null);
        }});
    }

    @Test
    public void testMakeUniqueWithAddAllMethod(){
        List<Bean> beans = new LinkiedList<>();
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});

        assertEquals(6, beans.size());

        Set<Bean> work = new LinkedHashSet<>();
        work.addAll(beans);
        beans.clear();
        beans.addAll(work);

        assertEquals(2, beans.size());
        assertEquals("b", beans.get(0).getName());
        assertEquals("c", beans.get(1).getName());
    }

    @Test
    public void testQ9842(){

        List<Bean> beans = new LinkedList<>();
        beans.add(new Bean(){{
            setId("1"); setName("hoge"); setAge(23);
        }});
        beans.add(new Bean(){{
            setId("2"); setName("hoge"); setAge(23);
        }});
        beans.add(new Bean(){{
            setId("3"); setName("pojo"); setAge(24);
        }});
        beans.add(new Bean(){{
            setId("1"); setName("hoge"); setAge(23);
        }});

        Set<Bean> work = new LinkedHashSet<>();
        work.addAll(beans);

        beans.clear();
        beans.addAll(work);

        assertEquals(3, beans.size());
        assertEquals("1", beans.get(0).getId());
        assertEquals("2", beans.get(1).getId());
        assertEquals("pojo", beans.get(2).getName());

    }}
}

ダイアモンド演算子つかってるので 1.7以降だろうということで、java1.7でコンパイルしてます。
junitは4です。

Beanでequalsとhashcodeをオーバーライドすれば可能です。
ただし、何をもって等しいとするかは設計次第ですので用途に合わせて適切に実装する必要があります。

示された Beanの場合は以下のような感じでしょうか。前述の通り等価とみなす仕様次第なのでそのまま使えるかはわかりません。
(コンストラクタに渡しているageの値がStringなのがちょっとひっかかりますが。)

```java
package qait9842;

public class Bean {
    private String id;
    private String name;
    private Integer age;

    @Override
    public boolean equals(Object obj){

        if (obj==null) return false;

        if (! (obj instanceof Bean) ) return false;
        if (this==obj) return true;

        Bean other = (Bean)obj;
        if(age != other.age) return false;
        if(id == null && other.id != null || id != null && other.id == null) return false;
        if(name == null && other.name != null || name != null && other.name == null ) return false;

        if(age == other.age && id.equals(other.id) && name.equals(name)) return true;

        return false;
    }

    @Override
    public int hashCode() {
        final int oddPrime = 31;
        int result = oddPrime;
        result += age;
        result *= oddPrime;
        result += (name == null) ? 0 : name.hashCode();
        result *= oddPrime;
        result += (id == null) ? 0 : id.hashCode();
        return result;
    }

// constructor
// getter, setter
}
```

適当ですけどこんなテストはパスします。

```java
package qait9842;

import static org.junit.Assert.*;

import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.junit.Test;

public class BeanTest {

    @Test
    public void testEqualsObject() {
        Bean a = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        Bean b = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        assertEquals(a, b);
        assertNotEquals(a, "a");
        assertNotEquals(a, new Bean());
        assertNotEquals(a, new Bean(){{
            setAge(0);
            setId("a");
            setName(null);
        }});
    }

    @Test
    public void testMakeUniqueWithAddAllMethod(){
        List<Bean> beans = new LinkiedList<>();
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});

        assertEquals(6, beans.size());

        Set<Bean> work = new LinkedHashSet<>();
        work.addAll(beans);
        beans.clear();
        beans.addAll(work);

        assertEquals(2, beans.size());
        assertEquals("b", beans.get(0).getName());
        assertEquals("c", beans.get(1).getName());
    }

    @Test
    public void testQ9842(){

        List<Bean> beans = new LinkedList<>();
        beans.add(new Bean(){{
            setId("1"); setName("hoge"); setAge(23);
        }});
        beans.add(new Bean(){{
            setId("2"); setName("hoge"); setAge(23);
        }});
        beans.add(new Bean(){{
            setId("3"); setName("pojo"); setAge(24);
        }});
        beans.add(new Bean(){{
            setId("1"); setName("hoge"); setAge(23);
        }});

        Set<Bean> work = new LinkedHashSet<>();
        work.addAll(beans);

        beans.clear();
        beans.addAll(work);

        assertEquals(3, beans.size());
        assertEquals("1", beans.get(0).getId());
        assertEquals("2", beans.get(1).getId());
        assertEquals("pojo", beans.get(2).getName());

    }}
}
```

ダイアモンド演算子つかってるので 1.7以降だろうということで、java1.7でコンパイルしてます。
junitは4です。

5599
 
     @Test
     public void testMakeUniqueWithAddAllMethod(){
-        List<Bean> beans = new ArrayList<>();
+        List<Bean> beans = new LinkiedList<>();
         beans.add(new Bean(){{
             setAge(0); setId("a"); setName("b");
         }});
 
         assertEquals(6, beans.size());
 
-        Set<Bean> work = new HashSet<>();
+        Set<Bean> work = new LinkedHashSet<>();
         work.addAll(beans);
         beans.clear();
         beans.addAll(work);
         assertEquals("b", beans.get(0).getName());
         assertEquals("c", beans.get(1).getName());
     }
+
+    @Test
+    public void testQ9842(){
+
+        List<Bean> beans = new LinkedList<>();
+        beans.add(new Bean(){{
+            setId("1"); setName("hoge"); setAge(23);
+        }});
+        beans.add(new Bean(){{
+            setId("2"); setName("hoge"); setAge(23);
+        }});
+        beans.add(new Bean(){{
+            setId("3"); setName("pojo"); setAge(24);
+        }});
+        beans.add(new Bean(){{
+            setId("1"); setName("hoge"); setAge(23);
+        }});
+
+        Set<Bean> work = new LinkedHashSet<>();
+        work.addAll(beans);
+
+        beans.clear();
+        beans.addAll(work);
+
+        assertEquals(3, beans.size());
+        assertEquals("1", beans.get(0).getId());
+        assertEquals("2", beans.get(1).getId());
+        assertEquals("pojo", beans.get(2).getName());
+
+    }}
 }
 ```
 

Beanでequalsとhashcodeをオーバーライドすれば可能です。
ただし、何をもって等しいとするかは設計次第ですので用途に合わせて適切に実装する必要があります。

示された Beanの場合は以下のような感じでしょうか。前述の通り等価とみなす仕様次第なのでそのまま使えるかはわかりません。
(コンストラクタに渡しているageの値がStringなのがちょっとひっかかりますが。)

package qait9842;

public class Bean {
    private String id;
    private String name;
    private Integer age;

    @Override
    public boolean equals(Object obj){

        if (obj==null) return false;

        if (! (obj instanceof Bean) ) return false;
        if (this==obj) return true;

        Bean other = (Bean)obj;
        if(age != other.age) return false;
        if(id == null && other.id != null || id != null && other.id == null) return false;
        if(name == null && other.name != null || name != null && other.name == null ) return false;

        if(age == other.age && id.equals(other.id) && name.equals(name)) return true;

        return false;
    }

    @Override
    public int hashCode() {
        final int oddPrime = 31;
        int result = oddPrime;
        result += age;
        result *= oddPrime;
        result += (name == null) ? 0 : name.hashCode();
        result *= oddPrime;
        result += (id == null) ? 0 : id.hashCode();
        return result;
    }

// constructor
// getter, setter
}

適当ですけどこんなテストはパスします。

package qait9842;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.junit.Test;

public class BeanTest {

    @Test
    public void testEqualsObject() {
        Bean a = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        Bean b = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        assertEquals(a, b);
        assertNotEquals(a, "a");
        assertNotEquals(a, new Bean());
        assertNotEquals(a, new Bean(){{
            setAge(0);
            setId("a");
            setName(null);
        }});
    }

    @Test
    public void testMakeUniqueWithAddAllMethod(){
        List<Bean> beans = new LinkiedList<>();
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});

        assertEquals(6, beans.size());

        Set<Bean> work = new LinkedHashSet<>();
        work.addAll(beans);
        beans.clear();
        beans.addAll(work);

        assertEquals(2, beans.size());
        assertEquals("b", beans.get(0).getName());
        assertEquals("c", beans.get(1).getName());
    }

    @Test
    public void testQ9842(){

        List<Bean> beans = new LinkedList<>();
        beans.add(new Bean(){{
            setId("1"); setName("hoge"); setAge(23);
        }});
        beans.add(new Bean(){{
            setId("2"); setName("hoge"); setAge(23);
        }});
        beans.add(new Bean(){{
            setId("3"); setName("pojo"); setAge(24);
        }});
        beans.add(new Bean(){{
            setId("1"); setName("hoge"); setAge(23);
        }});

        Set<Bean> work = new LinkedHashSet<>();
        work.addAll(beans);

        beans.clear();
        beans.addAll(work);

        assertEquals(3, beans.size());
        assertEquals("1", beans.get(0).getId());
        assertEquals("2", beans.get(1).getId());
        assertEquals("pojo", beans.get(2).getName());

    }}
}

ダイアモンド演算子つかってるので 1.7以降だろうということで、java1.7でコンパイルしてます。
junitは4です。

Beanでequalsとhashcodeをオーバーライドすれば可能です。
ただし、何をもって等しいとするかは設計次第ですので用途に合わせて適切に実装する必要があります。

示された Beanの場合は以下のような感じでしょうか。前述の通り等価とみなす仕様次第なのでそのまま使えるかはわかりません。
(コンストラクタに渡しているageの値がStringなのがちょっとひっかかりますが。)

```java
package qait9842;

public class Bean {
    private String id;
    private String name;
    private Integer age;

    @Override
    public boolean equals(Object obj){

        if (obj==null) return false;

        if (! (obj instanceof Bean) ) return false;
        if (this==obj) return true;

        Bean other = (Bean)obj;
        if(age != other.age) return false;
        if(id == null && other.id != null || id != null && other.id == null) return false;
        if(name == null && other.name != null || name != null && other.name == null ) return false;

        if(age == other.age && id.equals(other.id) && name.equals(name)) return true;

        return false;
    }

    @Override
    public int hashCode() {
        final int oddPrime = 31;
        int result = oddPrime;
        result += age;
        result *= oddPrime;
        result += (name == null) ? 0 : name.hashCode();
        result *= oddPrime;
        result += (id == null) ? 0 : id.hashCode();
        return result;
    }

// constructor
// getter, setter
}
```

適当ですけどこんなテストはパスします。

```java
package qait9842;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.junit.Test;

public class BeanTest {

    @Test
    public void testEqualsObject() {
        Bean a = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        Bean b = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        assertEquals(a, b);
        assertNotEquals(a, "a");
        assertNotEquals(a, new Bean());
        assertNotEquals(a, new Bean(){{
            setAge(0);
            setId("a");
            setName(null);
        }});
    }

    @Test
    public void testMakeUniqueWithAddAllMethod(){
        List<Bean> beans = new LinkiedList<>();
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});

        assertEquals(6, beans.size());

        Set<Bean> work = new LinkedHashSet<>();
        work.addAll(beans);
        beans.clear();
        beans.addAll(work);

        assertEquals(2, beans.size());
        assertEquals("b", beans.get(0).getName());
        assertEquals("c", beans.get(1).getName());
    }

    @Test
    public void testQ9842(){

        List<Bean> beans = new LinkedList<>();
        beans.add(new Bean(){{
            setId("1"); setName("hoge"); setAge(23);
        }});
        beans.add(new Bean(){{
            setId("2"); setName("hoge"); setAge(23);
        }});
        beans.add(new Bean(){{
            setId("3"); setName("pojo"); setAge(24);
        }});
        beans.add(new Bean(){{
            setId("1"); setName("hoge"); setAge(23);
        }});

        Set<Bean> work = new LinkedHashSet<>();
        work.addAll(beans);

        beans.clear();
        beans.addAll(work);

        assertEquals(3, beans.size());
        assertEquals("1", beans.get(0).getId());
        assertEquals("2", beans.get(1).getId());
        assertEquals("pojo", beans.get(2).getName());

    }}
}
```

ダイアモンド演算子つかってるので 1.7以降だろうということで、java1.7でコンパイルしてます。
junitは4です。

回答を投稿

Beanでequalsとhashcodeをオーバーライドすれば可能です。
ただし、何をもって等しいとするかは設計次第ですので用途に合わせて適切に実装する必要があります。

示された Beanの場合は以下のような感じでしょうか。前述の通り等価とみなす仕様次第なのでそのまま使えるかはわかりません。
(コンストラクタに渡しているageの値がStringなのがちょっとひっかかりますが。)

package qait9842;

public class Bean {
    private String id;
    private String name;
    private Integer age;

    @Override
    public boolean equals(Object obj){

        if (obj==null) return false;

        if (! (obj instanceof Bean) ) return false;
        if (this==obj) return true;

        Bean other = (Bean)obj;
        if(age != other.age) return false;
        if(id == null && other.id != null || id != null && other.id == null) return false;
        if(name == null && other.name != null || name != null && other.name == null ) return false;

        if(age == other.age && id.equals(other.id) && name.equals(name)) return true;

        return false;
    }

    @Override
    public int hashCode() {
        final int oddPrime = 31;
        int result = oddPrime;
        result += age;
        result *= oddPrime;
        result += (name == null) ? 0 : name.hashCode();
        result *= oddPrime;
        result += (id == null) ? 0 : id.hashCode();
        return result;
    }

// constructor
// getter, setter
}

適当ですけどこんなテストはパスします。

package qait9842;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.junit.Test;

public class BeanTest {

    @Test
    public void testEqualsObject() {
        Bean a = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        Bean b = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        assertEquals(a, b);
        assertNotEquals(a, "a");
        assertNotEquals(a, new Bean());
        assertNotEquals(a, new Bean(){{
            setAge(0);
            setId("a");
            setName(null);
        }});
    }

    @Test
    public void testMakeUniqueWithAddAllMethod(){
        List<Bean> beans = new ArrayList<>();
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});

        assertEquals(6, beans.size());

        Set<Bean> work = new HashSet<>();
        work.addAll(beans);
        beans.clear();
        beans.addAll(work);

        assertEquals(2, beans.size());
        assertEquals("b", beans.get(0).getName());
        assertEquals("c", beans.get(1).getName());
    }
}

ダイアモンド演算子つかってるので 1.7以降だろうということで、java1.7でコンパイルしてます。
junitは4です。

Beanでequalsとhashcodeをオーバーライドすれば可能です。
ただし、何をもって等しいとするかは設計次第ですので用途に合わせて適切に実装する必要があります。

示された Beanの場合は以下のような感じでしょうか。前述の通り等価とみなす仕様次第なのでそのまま使えるかはわかりません。
(コンストラクタに渡しているageの値がStringなのがちょっとひっかかりますが。)

```java
package qait9842;

public class Bean {
    private String id;
    private String name;
    private Integer age;

    @Override
    public boolean equals(Object obj){

        if (obj==null) return false;

        if (! (obj instanceof Bean) ) return false;
        if (this==obj) return true;

        Bean other = (Bean)obj;
        if(age != other.age) return false;
        if(id == null && other.id != null || id != null && other.id == null) return false;
        if(name == null && other.name != null || name != null && other.name == null ) return false;

        if(age == other.age && id.equals(other.id) && name.equals(name)) return true;

        return false;
    }

    @Override
    public int hashCode() {
        final int oddPrime = 31;
        int result = oddPrime;
        result += age;
        result *= oddPrime;
        result += (name == null) ? 0 : name.hashCode();
        result *= oddPrime;
        result += (id == null) ? 0 : id.hashCode();
        return result;
    }

// constructor
// getter, setter
}
```

適当ですけどこんなテストはパスします。

```java
package qait9842;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.junit.Test;

public class BeanTest {

    @Test
    public void testEqualsObject() {
        Bean a = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        Bean b = new Bean(){{
            this.setAge(0);
            this.setId("a");
            this.setName("b");
        }};

        assertEquals(a, b);
        assertNotEquals(a, "a");
        assertNotEquals(a, new Bean());
        assertNotEquals(a, new Bean(){{
            setAge(0);
            setId("a");
            setName(null);
        }});
    }

    @Test
    public void testMakeUniqueWithAddAllMethod(){
        List<Bean> beans = new ArrayList<>();
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("c");
        }});
        beans.add(new Bean(){{
            setAge(0); setId("a"); setName("b");
        }});

        assertEquals(6, beans.size());

        Set<Bean> work = new HashSet<>();
        work.addAll(beans);
        beans.clear();
        beans.addAll(work);

        assertEquals(2, beans.size());
        assertEquals("b", beans.get(0).getName());
        assertEquals("c", beans.get(1).getName());
    }
}
```

ダイアモンド演算子つかってるので 1.7以降だろうということで、java1.7でコンパイルしてます。
junitは4です。