2014-09-11 77 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