2014-09-11 79 views
1

我在Java中的代碼中遇到性能問題。我必須計算一個進程創建的每個對象的頻率。對象的類型是下面給出的「節點」。 目前我已經在test1中使用下面給出的HashMap類型技術解決了這個問題。然而,這個過程非常緩慢,因爲我的模擬生成了數百萬個對象。此外,我必須在每次迭代期間拆分字符串,然後重新連接,等等。所以我正在考慮像下面在test2中給出的那樣應用技術。但是HashMap會將每個新對象視爲新條目,而不管對象內的內容如何。 我想知道如果有人知道如何有效地解決這個問題。您Node類中Java中的性能問題

public class NewMain { 

/** 
* @param args the command line arguments 
*/ 
public static void main(String[] args) { 
    // TODO code application logic here 
     String[] a={"c","d"}; 
     int[] b={1,2}; 

    Map<String, Integer> test1=new HashMap<>(); 
    test1.put(new Node(a, b).toString(), 1); 
    test1.put(new Node(a, b).toString(), 3); 
    System.out.println(test1.size()); // size is 1 

     ////////////////////////// 
     Map<Node, Integer> test2=new HashMap<>(); 
     test2.put(new Node(a, b), 1); 
     test2.put(new Node(a, b), 3); 
     System.out.println(test2.size()); // size is 2 

} 
} 
    class Node{ 
    String[] a; 
    int[] b; 

public Node(String[] a, int[] b) { 
    this.a = a; 
    this.b = b; 
} 
public String toString(){ 
String result=null; 
    for(String e:a) 
     result+=e+"|"; 
    for(int e:b) 
     result+=e+"|"; 
    return result; 
} 

} 
+3

覆蓋'hashCode'你'Node'類? – 2014-09-11 00:28:51

+3

@ C.B。和'equals' – resueman 2014-09-11 00:30:18

+0

您使用'String'而不是'Node'作爲關鍵字的任何特定原因? – Amadan 2014-09-11 00:31:21

回答

0

試試這個:

@Override 
public int hashCode() { 
    int result = 1; 
    for(String e:a) 
     result = result * 31 + e.hashCode(); 
    for(int e:b) 
     result = result * 31 + e; 
    return result; 
} 

@Override 
public boolean equals(Object obj) { 
    return this.hashCode() == obj.hashCode(); 
} 

這告訴Java的人們應該通過比較它們的散列碼進行比較的對象 - 默認是隻比較指針,並確保哈希碼根據班級內容計算。這會給你1的結果你的test2.size()電話。


或者,基於上面@ bjlee72的建議是,Eclipse給我:

@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + Arrays.hashCode(a); 
    result = prime * result + Arrays.hashCode(b); 
    return result; 
} 
@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    Node other = (Node) obj; 
    if (!Arrays.equals(a, other.a)) 
     return false; 
    if (!Arrays.equals(b, other.b)) 
     return false; 
    return true; 
} 
+0

非常好!只是一個簡單的問題。我只想使用字符串數組「a」。所以我刪除了hashCode()中的第二個循環。但是,避免即使是第一個循環,只是使用public int hashCode(){return a.hasCode();}會是一個問題。它雖然給出了正確的結果,但我想知道是否會有大量的內容碰撞。 – user3212493 2014-09-11 02:59:27

+0

現在你指出了,我的'equals'代碼的確存在碰撞風險,但Eclipse版本沒有。在執行'Map'時猜測,它可能會首先執行'hashCode'來進行快速比較,然後'equals'來檢查它是否僅僅是碰撞或實際匹配。請選擇我的Eclipse版本,因爲它會更可靠。 – 2014-09-11 03:14:53