java 当我们有 SortedMap/SortedSet 时,为什么还需要 TreeMap/TreeSet?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14743986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why do we need a TreeMap/TreeSet when we have SortedMap/SortedSet?
提问by user2027425
Ok so SortedMap
/ SortedSet
is an interface, and TreeMap
/ TreeSet
is it's implementation. Both of them keep the elements in sorted order, right? So why do we need TreeMap
/ TreeSet
?
好的,SortedMap
/SortedSet
是一个接口,TreeMap
/TreeSet
是它的实现。它们都按排序顺序保存元素,对吗?那么为什么我们需要TreeMap
/ TreeSet
?
回答by Thomas
Interfaces do not provide any functionality, they just define the general outline of a class in terms of the methods it provides. But there's no code inside SortedMap
/SortedSet
that implements how to actually achieve this functionality.
接口不提供任何功能,它们只是根据类提供的方法定义类的总体轮廓。但是SortedMap
/内部没有代码SortedSet
来实现如何实际实现此功能。
And as a matter of fact, you can often have multiple ways to realize the same functionality. Think of the interface java.util.Set
: you could implement it as a TreeSet
but also as a HashSet
. Usually, there are some trade-offs between different implementations: a hashset might provide faster access times on average, while a tree set may be better at keeping the order of its items.
事实上,您通常可以通过多种方式来实现相同的功能。想想接口java.util.Set
:您可以将它实现为 aTreeSet
也可以实现为HashSet
. 通常,不同实现之间存在一些权衡:散列集可能平均提供更快的访问时间,而树集可能更好地保持其项目的顺序。
Often enough, however, a developer doesn't really care about the implementation details, as long as they know that they can store items in a set and retrieve them. That basic idea, but not how to achieve it, is defined by the interface.
然而,通常情况下,开发人员并不真正关心实现细节,只要他们知道他们可以将项目存储在一个集合中并检索它们。接口定义了基本思想,而不是如何实现它。
This is also the reason you cannot instantiate an interface. If you try the following:
这也是不能实例化接口的原因。如果您尝试以下操作:
SortedSet<Integer> set = new SortedSet<Integer>();
your compiler will complain. That is because "SortedSet" does not really realize a set itself, it just defines what an implementation of a sorted set must provide in terms of methods.
你的编译器会抱怨。那是因为“SortedSet”本身并没有真正实现一个集合,它只是定义了一个有序集合的实现必须在方法方面提供什么。
Here's a contrived example. Imagine you want to offer a functionality to compute the percentage of positive integers in a set. You could define a method:
这是一个人为的例子。想象一下,您想要提供一个功能来计算集合中正整数的百分比。你可以定义一个方法:
public double getPercentageOfPositives(Set<Integer> set) {
if (set.size() == 0) {
return 0.0;
}
int count = 0;
for (Iterator<Integer> iter = set.iterator(); iter.hasNext();) {
if (iter.next() > 0) count++;
}
return 100.0 * count / set.size();
}
Here, you don't really care whether the user of your method gives you a TreeSet
or a HashSet
. It doesn't matter which principle the given class uses, because you're just calling the size()
method and the iterator()
method anyway. All you need is trust in the fact that any set will have these two methods. An interface gives you that trust.
在这里,您并不真正关心您的方法的用户是否给您 aTreeSet
或 a HashSet
。给定的类使用哪种原则并不重要,因为您只是在调用size()
方法和iterator()
方法。您所需要的只是相信任何集合都将具有这两种方法的事实。界面为您提供了这种信任。
Therefore your method signature only asks for a Set
, which is an interface that defines that all classes implementing it must provide (amongst others) a size()
and an iterator()
method. If you wrote it like this:
因此,您的方法签名只要求 a Set
,这是一个接口,它定义了实现它的所有类必须提供(除其他外) asize()
和一个iterator()
方法。如果你是这样写的:
public double getPercentageOfPositives(SortedSet<Integer> set) {
...
}
and I have an instance of HashSet
then I couldn't use your method even though HashSet
provides size()
and iterator()
as well. :-(
我有一个实例,HashSet
即使HashSet
提供了size()
,我也无法使用您的方法iterator()
。:-(
In that sense, an interface is like a super-class, it defines the commonalities that all classes must have that implement it. But it does not provide any functionality itself.
从这个意义上说,接口就像一个超类,它定义了所有实现它的类必须具有的共性。但它本身不提供任何功能。
Thus to come back to your original example of SortedSet
: this interface does not provide any functionality. It merely defines which methods a sorted set implementation must provide. TreeSet
is such an implementation.
因此,回到您最初的示例SortedSet
:此接口不提供任何功能。它只是定义了排序集实现必须提供哪些方法。TreeSet
就是这样的实现。
The same line of thought applies to SortedMap
.
同样的思路也适用于SortedMap
.
回答by Hyman
Right because we need interfaceswhen we have classes.
是的,因为当我们有类时我们需要接口。
SortedMap
and SortedSet
define functionality which is implemented by using trees with a TreeMap
and a TreeSet
.
SortedMap
并SortedSet
定义通过使用带有 aTreeMap
和 a 的树来实现的功能TreeSet
。
回答by Mikhail Vladimirov
SortedMap
/SortedSet
are interfaces, so you cannot instantiate them. TreeMap
/TreeSet
are classes and can be instantiated and used. The reason why do we need SortedMap
/SortedSet
is that there could be implementations other than Sun's tree-based ones.
SortedMap
/SortedSet
是接口,因此您无法实例化它们。 TreeMap
/TreeSet
是类,可以实例化和使用。我们需要SortedMap
/的原因SortedSet
是除了 Sun 的基于树的实现之外,可能还有其他实现。
回答by TastyCode
Here is a cheat sheet to get the big picture (Source is in the image)
这是获取大图的备忘单(来源在图片中)
回答by Dancrumb
The answer is in your question; SortedMap
and SortedSet
are interfaces. They define methods and properties, but they don't actually implement them, so they don't provide any functionality.
答案就在你的问题中;SortedMap
并且SortedSet
是接口。它们定义了方法和属性,但实际上并没有实现它们,因此它们不提供任何功能。
TreeMap
and TreeSet
are implementations of these interfaces.
TreeMap
并且TreeSet
是这些接口的实现。
Good OOP design practices recommend that you code to interfaces, not implementations. That means that all of your method signatures should refer to interfaces and not classes.
良好的 OOP 设计实践建议您对接口进行编码,而不是针对实现进行编码。这意味着您的所有方法签名都应该引用接口而不是类。
So you would do:
所以你会这样做:
Object squishObjects(SortedMap map);
instead of
代替
Object squishObjects(TreeMap map);
Object squishObjects(TreeMap map);
That way, if a better implementation of SortedMap
comes along, you can switch that in, without having to modify all of your methods that relied on TreeMap
.
这样一来,如果有更好的执行SortedMap
出现时,你可以切换,在,而不必修改所有的方法是依靠TreeMap
。