在一行的 retainAll 之后将 size() 添加到 keySet()
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()
没有 return 副本。 return 是另一种观点。 从 .keySet()
returns 中删除元素将从原始地图中删除它们!
因此,此代码将给出正确的答案...并且还会损坏您的 phone书籍。
如果必须使用 retainAll
,则必须复制一份。不,无法链接 size()
调用。
但是,复制在这里很愚蠢。你真的只是想,嗯,数名字。这段代码不会破坏原始的 phone 书,而且速度要快得多:
int count = 0;
for (String n : names) if (phoneBook.containsKey(n)) count++;
return count;
这也显示了 'worrying about lines' 的愚蠢。上面的代码是 3 行,并且可以按原样合理地阅读。当然,很多使用 lambda 的人会将完全相同的 'semantic load' 放在一行中。但这并不是特别常用的代码风格。在某些时候,您 'measuring the efficacy of your code style' 比实际测量代码的复杂性还多。您还会看到毫无用处并使代码更难阅读的极端情况:一个 .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
很大。
我正在试验视图。是否有可能在不使用 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()
没有 return 副本。 return 是另一种观点。 从 .keySet()
returns 中删除元素将从原始地图中删除它们!
因此,此代码将给出正确的答案...并且还会损坏您的 phone书籍。
如果必须使用 retainAll
,则必须复制一份。不,无法链接 size()
调用。
但是,复制在这里很愚蠢。你真的只是想,嗯,数名字。这段代码不会破坏原始的 phone 书,而且速度要快得多:
int count = 0;
for (String n : names) if (phoneBook.containsKey(n)) count++;
return count;
这也显示了 'worrying about lines' 的愚蠢。上面的代码是 3 行,并且可以按原样合理地阅读。当然,很多使用 lambda 的人会将完全相同的 'semantic load' 放在一行中。但这并不是特别常用的代码风格。在某些时候,您 'measuring the efficacy of your code style' 比实际测量代码的复杂性还多。您还会看到毫无用处并使代码更难阅读的极端情况:一个 .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
很大。