我正在試驗視圖。是否有可能在不使用 lambdas 的情況下在倒數第二行撰寫 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
}
uj5u.com熱心網友回復:
這段代碼不能正常作業。
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 種不同事情的 etc 操作,全部堆在一個巨大的行上,一些小丑說:哈!看!更短!
牢記資料結構的特征。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很大。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/317310.html
