2014-10-31 41 views
2

我必須使用可以插入大量重複值的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「學生」的獨特性。那就是爲什麼hashCode()和equals()方法的作用是由這些屬性。所以根據這種實現方式,s3和s4是彼此重複的,即使認爲它們的屬性彼此不同也不例外。

  • HashSet是無序的。

  • 當S4組中的添加,我們可以看到從出端起S4從組和S3遺體丟棄。

  • 假設我要添加學生s100 = new Student(3, 3, "Bulbul", "earlier instance suppressed");的另一個目的是S3的重複。讓我們在插入s100之前插入很多s3的副本。

問:
由於集是無序和重複劑量不存在設定,在那個時候,S3被S100刪除的任何可能性?我想堅持早先的對象,拋棄後者。少量的數據並不能說明事實。我認爲在這種情況下可以使用排序的Set。但HashSet可以達到這個目的嗎?

在此先感謝。

回答

6

HashSet.add(E e)如果該集合已經包含指定的元素,則保持集合不變。因此,s3將不會被s100刪除。

+0

一個很好的把戲。我會記住它。非常感謝 – Razib 2014-10-31 10:09:44

3

如果你不想在你設定的碰撞,你需要重新定義你的散列函數,包括在它更多的數據,如getSrNo。關係數據庫傳統上使用唯一的主鍵爲每個新條目自動生成。 「StudentID」或類似的東西,這在整個學校應該是獨一無二的。