简体   繁体   English

字符串或对象比较的Java哈希集

[英]Java hashset of strings or objects comparision

I developed a Java module that checks if any component on a JFrame form has changed its value(text) and puts the component it into a HashSet for the JFrame. 我开发了一个Java模块,该模块检查JFrame表单上的任何组件是否已更改其值(文本),并将其放入JFrame的HashSet中。

Currently, I put the component name(String type) into the HashSet when its value/text changed. 当前,当其值/文本更改时,我将组件名称(字符串类型)放入HashSet中。

I have a second thought that if I put Object(the component with changed value) into the HashSet thinking it might save time compared to using component name(String). 我有第二个想法,如果我将Object(具有更改后的值的组件)放入HashSet中,则认为与使用组件名称(字符串)相比,它可以节省时间。

Here, my question is which is faster/efficent between 在这里,我的问题是

  • using String(component's name) to HashSet, or 使用String(组件的名称)到HashSet,或者
  • using Object(component itself) to HashSet? 使用对象(组件本身)到HashSet?

In short, maybe, which is cheaper? 简而言之,也许更便宜? String comparision or Object comparision? 字符串比较还是对象比较?

Thank you, 谢谢,

JB JB

Martin's answer is correct, stop worrying about performance unless you know for sure that you have a significant performance problem which has a practical negative effect in your product. Martin的答案是正确的,除非您确定自己存在严重的性能问题,而这实际上会对您的产品产生负面影响,否则不要担心性能。

But to answer the question: 但是要回答这个问题:

If you use a HashSet , then performance will depend on whether the components implement hashCode() , and if so, how expensive their hashCode() computation is. 如果使用HashSet ,则性能将取决于组件是否实现hashCode() ,如果是,则取决于其hashCode()计算的成本。 Most chances are that they do not even implement hashCode() , so their hash codes will essentially be their Identity Hash Codes , (look it up,) so putting objects in the map instead of strings will be infinitesimally faster. 大多数机会是它们甚至没有实现hashCode() ,因此它们的哈希码本质上将是它们的身份哈希码 ,(查找它),因此将对象而不是字符串放入映射中将无限快。 We are talking about clock cycles here. 我们在这里谈论时钟周期。

The same applies to comparisons: the components probably do not implement equals() either, so they will be compared by reference, which is going to be slightly faster than comparing strings. 比较也是如此:这些组件可能也不实现equals() ,因此它们将通过引用进行比较,这将比比较字符串要快一些。

If "probably" is not good enough for you, and if you cannot look at the source code of these components, then you can use an IdentityHashSet instead of a HashSet , to guarantee that only identity hash codes and reference comparisons will be used. 如果“可能”对您来说不够好,并且您无法查看这些组件的源代码,则可以使用IdentityHashSet代替HashSet ,以确保仅使用身份哈希码和引用比较。

But who cares. 但谁在乎。 The best approach by far is to do whatever is simpler, more understandable, and more maintainable. 到目前为止,最好的方法是做任何更简单,更易理解和更可维护的事情。

Cheapness of the insertion should not be an overriding concern at the development stage. 在开发阶段,插入的便宜不应成为首要问题。 equals methods are generally not expensive to execute for objects. 对对象而言, equals方法通常并不昂贵。 You should start with whatever gives you the least code complexity and only start targeting efficiency only if performance becomes a concern. 您应该从任何给您带来最少代码复杂性的东西开始,并且只有在性能成为问题时才开始针对效率。 Also, the comparison won't even take place unless there is a collision on the hashcode for items inserted into the set. 而且,除非插入集合中的项目的hashcode发生冲突,否则甚至不会进行比较。

I just tested my own two choices for the element type of HashSet in Java. 我刚刚针对Java中的HashSet的元素类型测试了自己的两个选择。 The result says everything I think. 结果说明了我的想法。

HashSet element type: Object, experiment count: 1000, Elapsed time: 16ms
HashSet element type: Object, experiment count: 1000, Elapsed time: 8ms
HashSet element type: Object, experiment count: 1000, Elapsed time: 8ms
HashSet element type: String, experiment count: 1000, Elapsed time: 124ms
HashSet element type: String, experiment count: 1000, Elapsed time: 110ms
HashSet element type: String, experiment count: 1000, Elapsed time: 130ms

You know, Java still has some bad reputation on its execution speed. 您知道,Java在执行速度上仍然享有一定的声誉。 What kind of HashSet element type would you use? 您将使用哪种HashSet元素类型?

Here is my code that showed above result. 这是上面结果显示的我的代码。

boolean StringUsed = true;

changedComponents = new HashSet<Component>() {};
changedComponentNames = new HashSet<String>() {};

private void changeValueManyTimes() {
    long start = System.currentTimeMillis();

    for (int i = 0; i<count; i++) {
        recordStatisticsCheckBox.setSelected
            (!recordStatisticsCheckBox.isSelected());
    }
    long stop = System.currentTimeMillis();
    System.out.print("HashSet element type: " +
        (StringUsed ? "String" : "Object") + ", experiment count: " + count);
        System.out.println(", Elapsed time: " + (stop - start) + "ms");
        System.out.println("");
}

public static int count = 1000;      
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    StringUsed = false;
    changeValueManyTimes();
}                                        

private void recordStatisticsCheckBoxStateChanged     
    (javax.swing.event.ChangeEvent evt) {                                                      
    recordStatisticsCheckBoxActionPerformed(null);
}                                                     

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    StringUsed = true;
    changeValueManyTimes();        
}    

private void recordStatisticsCheckBoxActionPerformed 
    (java.awt.event.ActionEvent evt) {                                                         
    if (StringUsed) {
        if (recordStatisticsCheckBox.isSelected() == origSelection) {
            changedComponents.remove(recordStatisticsCheckBox);
        } else {
            changedComponents.add(recordStatisticsCheckBox);     
        }
        changeSaveEnabledIfNeeded();
    } else {
        if (recordStatisticsCheckBox.isSelected() == origSelection) {
           changedComponentNames.remove(recordStatisticsCheckBox.getName());
        } else {
           changedComponentNames.add(recordStatisticsCheckBox.getName());     
        }
        changeSaveEnabledIfNeeded();
    }
}

private void changeSaveEnabledIfNeeded() {
    if (changedComponents.size() == 0)
        saveButton.setEnabled(false);
    else
        saveButton.setEnabled(true);    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM