我理解Java最佳实践表明,在声明变量时,通用集合接口用于在左侧声明,而特定实现在右侧。
因此,如果我必须声明Set接口,正确的方法是,
Set<String> set = new TreeSet<>();
但是,通过此声明,我无法访问set.last()
方法。
但是当我以这种方式宣布时,
TreeSet<String> set = new TreeSet<>();
我可以访问,last()
和first()
。
有人能帮助我理解为什么吗?
答案 0 :(得分:4)
last()
和first()
是属于TreeSet
的特定方法,而不是通用接口Set
。当您引用变量时,它会查看源类型而不是分配的类型,因此如果您将TreeSet
存储为Set
,则只能将其视为Set
}。这基本上隐藏了附加功能。
例如,Java中的每个类都扩展了Object
。因此,这是一个完全有效的分配:
final Object mMyList = new ArrayList<String>();
但是,如果不直接引用ArrayList
而不应用 type-casting ,我们将永远无法使用mMyList
样式功能,因为所有Java都可以告诉它是处理通用Object
;仅此而已。
答案 1 :(得分:2)
您可以使用SortedSet接口作为声明(具有first()
和last()
方法)。
答案 2 :(得分:1)
Set
的界面未提供last()
和first()
,因为Set
并不总是有意义。
Java是一种静态类型语言。当编译器看到您执行set.last()
时,因为期望set
成为Set
。它不知道set
是TreeSet
是last()
,还是HashSet
不是TreeSet
。这就是为什么抱怨。
等一下。您不需要在此使用具体类TreeSet
声明它。 SortedSet
带有Set
接口,提供此类方法。换句话说:因为您需要使用已排序的first()
(为此提供last()
和SortedSet
才有意义),您应该使用的接口应该是{ {1}}代替Set
因此你应该做的是
SortedSet<String> set = new TreeSet<>();
答案 3 :(得分:0)
要在此处添加现有答案,原因是TreeSet
实现了接口NavigableSet
,该接口从接口java.util.SortedSet
继承了方法比较器 first ,最后和分隔符。
相反,Set
却没有SortedSet
方法,因为它不是从那里继承的。
从更多Java TreeSet examples中签出。