簡體   English   中英

字符串或對象比較的Java哈希集

[英]Java hashset of strings or objects comparision

我開發了一個Java模塊,該模塊檢查JFrame表單上的任何組件是否已更改其值(文本),並將其放入JFrame的HashSet中。

當前,當其值/文本更改時,我將組件名稱(字符串類型)放入HashSet中。

我有第二個想法,如果我將Object(具有更改后的值的組件)放入HashSet中,則認為與使用組件名稱(字符串)相比,它可以節省時間。

在這里,我的問題是

  • 使用String(組件的名稱)到HashSet,或者
  • 使用對象(組件本身)到HashSet?

簡而言之,也許更便宜? 字符串比較還是對象比較?

謝謝,

JB

Martin的答案是正確的,除非您確定自己存在嚴重的性能問題,而這實際上會對您的產品產生負面影響,否則不要擔心性能。

但是要回答這個問題:

如果使用HashSet ,則性能將取決於組件是否實現hashCode() ,如果是,則取決於其hashCode()計算的成本。 大多數機會是它們甚至沒有實現hashCode() ,因此它們的哈希碼本質上將是它們的身份哈希碼 ,(查找它),因此將對象而不是字符串放入映射中將無限快。 我們在這里談論時鍾周期。

比較也是如此:這些組件可能也不實現equals() ,因此它們將通過引用進行比較,這將比比較字符串要快一些。

如果“可能”對您來說不夠好,並且您無法查看這些組件的源代碼,則可以使用IdentityHashSet代替HashSet ,以確保僅使用身份哈希碼和引用比較。

但誰在乎。 到目前為止,最好的方法是做任何更簡單,更易理解和更可維護的事情。

在開發階段,插入的便宜不應成為首要問題。 對對象而言, equals方法通常並不昂貴。 您應該從任何給您帶來最少代碼復雜性的東西開始,並且只有在性能成為問題時才開始針對效率。 而且,除非插入集合中的項目的hashcode發生沖突,否則甚至不會進行比較。

我剛剛針對Java中的HashSet的元素類型測試了自己的兩個選擇。 結果說明了我的想法。

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

您知道,Java在執行速度上仍然享有一定的聲譽。 您將使用哪種HashSet元素類型?

這是上面結果顯示的我的代碼。

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