java - 什么时候我们需要泛型 <> 表示法?

标签 java generics

我正在阅读有关 MinPQ 的实现的信息我对何时使用泛型符号有点困惑。之前,我假设您仅在与类相关时执行此操作,例如在返回类型中,或在 Iterable<Key> 中的接口(interface)中。 。一直是对的,直到遇到下面的用法。

public class MinPQ<Key> implements Iterable<Key> { //I understand this
    public MinPQ(int initCapacity) {
        pq = (Key[]) new Object[initCapacity + 1];
        N = 0;
    }  //also clear

    public Iterator<Key> iterator() { return new HeapIterator(); }

    private class HeapIterator implements Iterator<Key> { 
    // Why does HeapIterator not need the generic notation here?

        private MinPQ<Key> copy;
        public HeapIterator() {
            if (comparator == null) 
                copy = new MinPQ<Key>(size());
                //where does this generics come from, no constructor is declared this way
            else                   
                copy = new MinPQ<Key>(size(), comparator);

            for (int i = 1; i <= N; i++)
                copy.insert(pq[i]);
        }
    }
}

这是为什么

private class HeapIterator implements Iterator<Key>

而不是

private class HeapIterator<Key> implements Iterator<Key>

此外,当我们调用构造函数时,类声明是它是否使用泛型的唯一决定因素吗?

最佳答案

让我们从一个更简单的示例开始。考虑这个类声明:

public class IntIterator implements Iterator<Integer>

这是做什么的?它定义了一个实现 Iterator 的类,但它仅适用于 Integer类型。此类已预定义了实现 next() 时将使用的类型。 , next()必须返回 Integer因为这是它通过指定特定类型声明的接口(interface)。

现在如果我想要一个更通用的迭代器怎么办?我可能会定义一个这样的类:

public class GeneralIterator<T> implements Iterator<T>

这看起来有些相似,但非常不同。在这里,我说过,“我的 GeneralIterator 是一个泛型类。您必须告诉我它适用于什么类型,并且所有 Iterator 方法都将使用您告诉我的相同类型。”在这里,GeneralIterator<T>创建类型参数,并且 Iterator<T>正在使用该类型参数。

现在让我们仔细看看您的示例。让我们从顶级类定义开始:

public class MinPQ<Key> implements Iterable<Key>

你说你明白这一点。好的!你懂的,这就像我的GeneralIterator<T>上面的例子。 MinPQ<Key> 创建一个名为 Key 的类型参数,并且它声明它实现 Iterable 使用该类型参数。现在我们只剩下令人困惑的部分,即内部类声明:

private class HeapIterator implements Iterator<Key>

这更像是我的第一个示例,但也有一点不同。它没有指定具体的类,而是重用 MinPG<Key> 创建的泛型类型参数。 。这是完全有道理的。 HeapIterator不想创建自己的类型参数;它想使用与外部类相同的类!这正是它正在做的事情。这一切意味着HeapIterator的执行使用与其外部相同的类型 MinPG<Key> .

如果他们写了:

private class HeapIterator<Key> implements Iterator<Key>

那将会非常不同。这将使 HeapIterator创建一个类型参数,该参数可能与 MinPG<Key> 定义的不同.

有了这种理解,新的 MinPG<Key> 的实例化在HeapIterator的构造函数稍微简单一些。这再次使用 MinPG<Key> 定义的类型参数。它只是说,“MinPG 的这个实例必须使用与原始实例相同的类型”,而不是允许 HeapIterator 中使用不同的类型。类。

TL;DR:这一切都是为了确保所有对象的类型匹配,并且不允许出现类型不同的奇怪情况。

关于java - 什么时候我们需要泛型 <> 表示法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28313061/

相关文章:

java - 将 List<String> 转换为 List<Integer>(或任何扩展 Number 的类)

java - IntelliJ IDEA 代码折叠

java - 为什么我们不能从逆变类型读取

C# - 根据类型将对象转换为 IList<T>

java - 带有可选的泛型

java - 在 Java 中最好没有工厂的情况下克隆通用对象的有效方法

java - 在单词中的每个字符之间插入一个字符(a 到 z)

java - 如果我们在字符串中有所需的货币代码,我们如何更改 freemarker 上的默认货币?

java - 为什么我没有使用100%?

java - 如何在java中获取当前的maven配置文件ID