HashSet - ensuring the earlier object persistence

2019-05-27 02:08发布

I have to use a HashSet where a lot of duplicate value may be inserted. But I want to preserve the earlier data inserted in the hash when a later insertion makes the duplicate. To examine this I have write the following code and insert many duplicate value, but it doesn't satisfy me. Please see the code below -

import java.util.HashSet;
import java.util.Set;

public class SetTest {

    private static Set<Student> studentSet = new HashSet<Student>();
    private static Student s1, s2, s3, s4, s5, s6, s7, s8, s9;

    public static void main(String args[]){

        s1 = new Student(1, 1, "Syeful", "first boy");
        s2 = new Student(2, 2, "Razib", "no comments");
        s3 = new Student(3, 3, "Bulbul", "should remain");
        s4 = new Student(4, 3, "Bulbul", "should not remain");
        s5 = new Student(5, 4, "Bulbul", "should remain");
        s9 = new Student(9, 5, "Proshanto", "kaka - my favourite");

        studentSet.add(s1);
        studentSet.add(s2);
        studentSet.add(s3);
        studentSet.add(s4);
        studentSet.add(s5);
        studentSet.add(s9);

        for(Student each : studentSet){
            System.out.println("SrNo: " +each.getSrNo()+ " roleNo: " 
                    +each.getRoleNo()+ " name: " +each.getName()+ 
                    " coment: " +each.getComment());
        }
    }

}

class Student{

    private int srNo;
    private int roleNo;
    private String name;
    private String comment;

    public Student(int srNo, int role, String name, String comment) {
        super();
        this.srNo = srNo;
        this.roleNo = role;
        this.name = name;
        this.comment = comment;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + roleNo;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof Student)) {
            return false;
        }
        Student other = (Student) obj;
        if (name == null) {
            if (other.name != null) {
                return false;
            }
        } else if (!name.equals(other.name)) {
            return false;
        }
        if (roleNo != other.roleNo) {
            return false;
        }
        return true;
    }

    public int getSrNo() {
        return srNo;
    }

    public int getRoleNo() {
        return roleNo;
    }

    public String getName() {
        return name;
    }

    public String getComment() {
        return comment;
    }
}

And the output is:

Set Size: 5
SrNo: 9 roleNo: 5 name: Proshanto coment: kaka - my favourite
SrNo: 2 roleNo: 2 name: Razib coment: no comments
SrNo: 1 roleNo: 1 name: Syeful coment: first boy
SrNo: 5 roleNo: 4 name: Bulbul coment: should remain
SrNo: 3 roleNo: 3 name: Bulbul coment: should remain

It seems me to clarify some points before asking the questions so that I can explain it properly and clarify my understanding as well.

  • I want to maintain the uniqueness of 'Student' based on roleNo and name.That's why the hashCode() and equals() role is made up with these property. So according to this implementation s3 and s4 are duplicate of each other even thought the comment , srNo property of them differs from each other.

  • HashSet is unordered.

  • When s4 is added in the set, we can see from the out put that s4 is discarded from the set and s3 remains.

  • Suppose I want to add another object of student s100 = new Student(3, 3, "Bulbul", "earlier instance suppressed"); which is the duplicate of s3. Let we have inserted a lot of duplicate of s3 before inserting s100.

Question:
Since set is unsorted and the duplicate dose not exist in set, is there any possibility that the s3 is removed by s100? I want to persist the earlier object discarding the later one. The small amount of data is not clarifying the fact. I think in this case a sorted Set may used. But does the HashSet can serve the purpose?

Thanks in advance.

2条回答
我只想做你的唯一
2楼-- · 2019-05-27 02:29

If you do not want collisions in your set, you need to redefine your hashing function to include more data in it, such as getSrNo. Relational Databases traditionally perform this using a unique primary key which is automatically generated for every new entry. This of "StudentID" or something like that, which should be unique across the school.

查看更多
啃猪蹄的小仙女
3楼-- · 2019-05-27 02:31

HashSet.add(E e) leaves the set unchanged if it already contains the specified element. So, there are no circumstances where s3 would be removed by s100.

查看更多
登录 后发表回答