[英]Add size() to keySet() after retainAll on one line
我正在試驗視圖。 是否可以在不使用 lambda 的情況下在倒數第二行編寫 size() 方法? 如下:
eintraege.retainAll(Arrays.asList(names)).size(); // Does not work
public static int countNames(Map<String, PhoneNumber> phoneBook,
String[] names) {
Set<String> eintraege = phoneBook.keySet();
eintraege.retainAll(Arrays.asList(names));
return eintraege.size(); // Works fine
}
此代碼無法正常工作。
retainAll
將刪除所有不在names
中的鍵。 .keySet()
不返回副本。 它返回不同的視圖。 從.keySet()
返回的內容中刪除元素會將它們從原始地圖中刪除!
因此,此代碼將給出正確的答案...並且還會損壞您的電話簿。
如果您必須使用retainAll
,則必須制作一份副本。 不,沒有辦法鏈接size()
調用。
但是,在這里復制是愚蠢的。 你真的只是想,嗯,數名字。 此代碼不會破壞原始電話簿並且速度更快:
int count = 0;
for (String n : names) if (phoneBook.containsKey(n)) count++;
return count;
它還顯示了“擔心台詞”的愚蠢行為。 上面的代碼是 3 行,並且可以按原樣合理地閱讀。 當然,大量使用 lambda 的人會將完全相同的“語義負載”放在一行中。 但這並不是特別常用的代碼風格。 在某些時候,您更多地是在“衡量代碼風格的有效性”,而不是實際衡量代碼的復雜性。 您還會看到毫無用處並使代碼更難閱讀的極端情況:一個.stream().map()
等操作執行 18 項不同的操作,全部堆積在一條巨大的線上,並且有些小丑在說:哈! 看! 更短!
牢記數據結構的特征。 list.contains(n)
花費的時間隨着列表的大小而增加。 map.containsKey(n)
或set.contains(n)
需要常數時間(或者在TreeMap
的情況下,需要的時間與log2(n)
成比例,但請記住log2(1_000_000)
仍然只有幾十循環。即使對於巨大的輸入,計算機也可以進行對數縮放。
因此,上面的代碼相對較快,但是如果你翻轉它:
for (String n : phoneBook.keySet()) if (names.contains(n)) count++;
這確實會變得非常緩慢,尤其是當names
很大的時候。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.