4

好的,所以SortedMap/SortedSet是一个接口,而TreeMap/TreeSet是它的实现。他们都保持元素排序,对吧?那么为什么我们需要TreeMap/ TreeSet

4

5 回答 5

13

接口不提供任何功能,它们只是根据它提供的方法定义一个类的大致轮廓。SortedMap但是/内部没有代码SortedSet实现如何实际实现此功能。

事实上,您通常可以有多种方法来实现相同的功能。想一想接口java.util.Set:您可以将其实现为 aTreeSet也可以实现为HashSet. 通常,不同实现之间存在一些权衡:哈希集可能平均提供更快的访问时间,而树集可能更好地保持其项目的顺序。

然而,通常情况下,开发人员并不真正关心实现细节,只要他们知道他们可以将项目存储在集合中并检索它们。这个基本思想,但不是如何实现它,是由接口定义的。

这也是您无法实例化接口的原因。如果您尝试以下操作:

SortedSet<Integer> set = new SortedSet<Integer>();

你的编译器会抱怨。那是因为“SortedSet”本身并没有真正实现一个集合,它只是定义了一个有序集合的实现必须在方法方面提供什么。

这是一个人为的例子。想象一下,您想提供一个计算集合中正整数百分比的功能。你可以定义一个方法:

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();
}

在这里,您并不真正关心您的方法的用户是给您 aTreeSet还是 a HashSet。给定类使用哪种原则并不重要,因为无论如何您只是在调用size()方法和方法。iterator()您所需要的只是相信任何集合都将具有这两种方法这一事实。一个界面给了你这种信任。

因此,您的方法签名只要求 a Set,这是一个接口,定义了所有实现它的类必须提供(以及其他)asize()和一个iterator()方法。如果你这样写:

public double getPercentageOfPositives(SortedSet<Integer> set) {
    ...
}

我有一个实例,HashSet即使HashSet提供了size(),我也无法使用您的方法iterator()。:-(

从这个意义上说,接口就像一个超类,它定义了所有实现它的类必须具有的共性。但它本身不提供任何功能。

因此回到你原来的例子SortedSet:这个接口不提供任何功能。它只定义了排序集实现必须提供的方法。TreeSet就是这样一个实现。

同样的思路也适用于SortedMap.

于 2013-02-07T05:11:55.663 回答
4

对,因为当我们有类时我们需要接口

SortedMapSortedSet定义通过使用带有 aTreeMap和 a 的树来实现的功能TreeSet

于 2013-02-07T05:12:17.670 回答
2

SortedMap/SortedSet是接口,所以你不能实例化它们。 TreeMap/TreeSet是类,可以实例化和使用。我们需要SortedMap/的原因SortedSet是除了 Sun 的基于树的实现之外,可能还有其他实现。

于 2013-02-07T05:13:04.487 回答
1

这是一张用于获取大图的备忘单(来源在图片中)

在此处输入图像描述

于 2014-12-05T06:23:28.620 回答
0

答案就在你的问题中;SortedMap并且SortedSet是接口。它们定义了方法和属性,但实际上并没有实现它们,因此它们不提供任何功能。

TreeMap并且TreeSet是这些接口的实现。

良好的 OOP 设计实践建议您对接口而不是实现进行编码。这意味着您的所有方法签名都应该引用接口而不是类。

所以你会这样做:

Object squishObjects(SortedMap map);

代替

Object squishObjects(TreeMap map);

这样,如果出现更好的实现SortedMap,您可以将其切换,而无需修改所有依赖于TreeMap.

于 2013-02-07T05:14:56.427 回答