HashSet - 确保早期的对象持久性

时间:2014-10-31 06:38:51

标签: java hash collections set hashset

我必须使用HashSet,其中可能会插入大量重复值。但是,当稍后插入复制时,我想保留插入到哈希中的早期数据。为了检查这一点,我编写了以下代码并插入了许多重复值,但它并不能满足我。请参阅下面的代码 -

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;
    }
}

输出是:

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

在询问问题之前,我似乎要澄清一些要点,这样我才能正确解释并澄清我的理解。

  • 我想基于roleNoname维护'Student'的唯一性。这就是hashCode()和equals()角色由这些属性组成的原因。因此,根据此实现,s3和s4彼此重复,即使它们的commentsrNo属性彼此不同。

  • HashSet无序。

  • 当在集合中添加s4时,我们可以从输出中看到s4被从集合中丢弃并且s3仍然存在。

  • 假设我想添加另一个学生s100 = new Student(3, 3, "Bulbul", "earlier instance suppressed");的对象,它是s3的副本。我们在插入s100之前插入了很多s3的副本。

问题:
由于集合未排序且集合中不存在重复剂量,是否有可能通过 s100 删除s3?我想坚持早期的对象丢弃后者。少量数据并未澄清事实。我认为在这种情况下可以使用排序的Set。但是HashSet可以达到目的吗?

提前致谢。

2 个答案:

答案 0 :(得分:6)

如果

HashSet.add(E e)已包含指定的元素,则

{{3}}将保持不变。因此,s3无法删除s100

答案 1 :(得分:3)

如果您不想在集合中发生冲突,则需要重新定义散列函数以在其中包含更多数据,例如getSrNo。关系数据库传统上使用为每个新条目自动生成的唯一主键来执行此操作。这是“学生ID”或类似的东西,在整个学校应该是独一无二的。