封装:为什么名称keySet in java

Encapsulation: why the name keySet in java

在java中,我们可以使用方法keySet来获取映射中的所有键。但我想知道为什么方法名称不只是keys?名字 Set 不是泄露了实现的细节吗?

根据我的理解,Java 是静态类型语言,在名称中包含类型毫无意义。无论如何,调用代码必须具有正确的接口类型。如果我们假设这个策略是正确的,那么每个方法都必须有类型前缀,这没有任何意义。我认为@JBNizet 在他的评论中正确陈述了选择背后的原因。

isn't the name Set leaks details about the implementation?

1) Set 是一个接口。
例如,如果该方法被命名为 keyHashSet(),那将不是一个好主意 因为 HashSetSet.

的实现

但是 keySet() 很好,因为 return 键入一个定义特定契约的接口,并使用在方法名称中传达该特定契约的名称是按接口编程的有效方法并且能够return以干净的方式Set的任何实现。

2) 除了在 Map 接口中选择 keys() 方法名称而不是 keySet() 也是不可能的。
正如@JB Nizet 在其评论中建议的那样,keys() 方法已在 JDK 集合 class 中定义:Enumeration<K> keys().
Dictionary class 中声明 HashTable 继承自 :

public class Hashtable<K,V>  extends Dictionary<K,V>...{

但是这个方法 : Enumeration<K> keys(); 没有 return Set.
所以 HashTable 既是 Dictionary 又是 Map :

public class Hashtable<K,V>  extends Dictionary<K,V>  implements Map<K,V>,

必须实施一种方法来 return 形式的 Enumeration 键,还有另一种方法 return 形式的 Set 键。
需要一个不同的命名来区分它们

您可能还注意到 Set<Map.Entry<K, V>> entrySet() 也在 Map 接口中定义,遵循相同的命名逻辑,而 HashTable 的其他层次结构没有定义 entries() 方法。
应该是一致的吧

isn't the name Set leaks details about the implementation?

声明 Set<K> keySet() 没有告诉我们更多关于 实施Set<K> keys() 会。在这两种情况下,我们都知道方法 returns a SetSet 是一个接口,而不是具体的 class。

将它包含在名称中是否是一个好主意是一个风格问题(个人而言,不,我不认为它是;但理性的人可能会有所不同)。但是这样做并没有告诉我们任何关于 实现 我们无论如何都不会知道的事情。

I was wondering why the method name is not just keys

就像现代 Java 中的许多东西一样,向后兼容性有点阻碍:keys() 已经被采用(被 java.util.Hashtable.keys() 使用,并且 class 应该仍然能够实施 Map),所以他们不得不选择其他东西。

Doesn't the name Set leaks details about the implementation ?

不,不是。 Map接口已经规定不能有重复键。所以根据定义,键的集合是 SetSet 仍然是一个接口,可以有不同的实现。