[英]Java hashset of strings or objects comparision
我開發了一個Java模塊,該模塊檢查JFrame表單上的任何組件是否已更改其值(文本),並將其放入JFrame的HashSet中。
當前,當其值/文本更改時,我將組件名稱(字符串類型)放入HashSet中。
我有第二個想法,如果我將Object(具有更改后的值的組件)放入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.