Java,泛型和迭代器

Som*_*ers 0 java generics

我试图理解为什么我收到此错误:

- 这是错误 -

File: ...\HashTable.java [line: 103] Error: The return type is incompatible with HashTableInterface<Key,Value>.iterators()

该接口包含一个内部类:

public class Entry<Key, Value>{...}

和LinkedList类似于java API但它包含一个迭代器内部类,但在测试更简单的东西时:

- 这是工作代码,至少在drjava的交互窗格中 -

LinkedList<String> list = new LinkedList<String>();
Iterator<String> test = list.iterator();
Run Code Online (Sandbox Code Playgroud)

但我无法在我的HashTable类中编译此方法:

- 这是我无法工作的代码 -

public Iterator<Entry<Key, Value>> iterator(){
LinkedList<Entry<Key, Value>> iter = new LinkedList<Entry<Key, Value>>();
return iter.iterator();
}
Run Code Online (Sandbox Code Playgroud)

我认为它简单,它似乎并不太复杂,但任何输入都将非常感激.

**你是对的,它应该是list.iterator();

编辑

- 好吧,这是界面 -

import nhUtilities.containers2.*;

interface HashTableInterface<Key, Value> {

    public boolean isEmpty();

    public Value get(Key key);

    public void add(Key key, Value value);

    public void remove(Key key);

    public void clear();

    public Iterator<Entry<Key, Value>> iterator();

    public interface Entry<Key, Value> {

        public Key getKey();

        public Value getValue();

        public void setValue(Value value);

    }
}
Run Code Online (Sandbox Code Playgroud)

- 这是实现的条目,它是HashTable的内部类,其中被破坏的方法驻留在 -

public class Entry<Key, Value> {
    private Key k;
    private Value v;

    public Entry(Key key, Value value) {
        k = key;
        v = value;
    }

    /**
     * Returns a key of pair;
     */

    public Key getKey() {
        return this.k;
    }

    /**
     * Returns value of pair;
     */

    public Value getValue() {
        return this.v;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑+

所以我才意识到

public class LinkedList<Element> extends AbstractList<Element>

public abstract class AbstractList<Element> implements List<Element>

public interface List<Element> extends java.lang.Iterable<Element>

但在LinkedList里面却有

private class Iterator extends AbstractIterator<Element> implements nhUtilities.containers2.Iterator<Element>

也许这可能导致冲突(因为我使用的LinkedList不是java API LinkedList)?

Bor*_*der 7

List不是 Iterator.List 有一个 Iterator.List implements Iterable.

List<String> list = new LinkedList<String>();
Iterator<String> test = list.iterator();
                             //^^ here - you call iterator()
Run Code Online (Sandbox Code Playgroud)

你需要调用iterator()一个List来获取一个Iterator实例.

所以你应该阅读方法

public Iterator<Entry> iterator(){
    List<Entry> iter = new LinkedList<Entry>();
    return iter.iterator();
}
Run Code Online (Sandbox Code Playgroud)

一定要打电话iterator()List.

确保您的类implements Iterable<Entry>作为Iterable接口上的泛型类型参数在interface方法中得到回显.

编辑

从OP发布的类中,它看起来像EntryinterfaceEntryin iterator()方法之间的混淆.

你的Entry类是通用的<K,V>,你的方法根本不是通用的.

所以,你的接口要求你的iterator方法返回一个原始EntryEntry<?,?>iterator方法.

据推测,您的实现类实现了一个Entry<K,V>Iterator<Entry<K,V>>在其方法的实现中返回一个.

这与你的合同不相容interface.

你的interface方法应该是:

Iterator<Entry<Key,Value>> iterator();
Run Code Online (Sandbox Code Playgroud)

更普遍:

  1. interface应该扩展Iterable<Entry<K,V>>而不是添加自己的自定义方法,这允许您使用增强的for-each-loop.
  2. 按照样式约定,我们对通用类型参数使用单个字母,所以 HashTableInterface<K,V>
  3. 不要public在你的方法中使用interface- 默认interface方法是public这样只会增加噪音.

所以,你interface需要分成两部分,最后得到:

public interface Entry<K, V> {

    K getKey();

    V getValue();

    void setValue(V value);
}

public interface HashTableInterface<K, V> extends Iterable<Entry<K, V>> {

    boolean isEmpty();

    V get(K key);

    void add(K key, V value);

    void remove(K key);

    void clear();
}
Run Code Online (Sandbox Code Playgroud)

编辑MK2

一个List<Entry<K, V>>不一样List<TableEntry<K, V>>.

正如我一开始所怀疑的那样,你(令人困惑)有两个Entry类,一个嵌套在实现中interface,一个嵌套在实现中.

所以在你的情况下List<Entry<K, V>>是不一样的List<Entry<K, V>>.看看混乱的来源?

List就是执行Entry和你interface需要Entry的的interface类型.

同样Iterator<Entry..,方法返回的是错误的Entry类型.因此编译器抱怨你的实现没有实现你的Interface.

这是一个有效的例子;

class HashTable<K, V> implements HashTableInterface<K, V> {

    private class TableEntry<K, V> implements Entry<K, V> {
    }
    private final List<Entry<K, V>> entries = new LinkedList<>();

    @Override
    public Iterator<Entry<K, V>> iterator() {
        return entries.iterator();
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果我改变了ListList<TableEntry<K, V>>代码将无法编译.

对你来说,这里的关键点就是永远不要把课程叫做同样的事情,即使这看起来真是个好主意.