0

このエラーが発生する理由を理解しようとしています:

-- これはエラーです --

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

まだ、このメソッドを HashTable クラス内でコンパイルすることはできません。

-- これは私が作業できないコードです --

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

単純なものだと思いますが、それほど複雑ではないように見えますが、どんな意見でも大歓迎です。

** 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);

    }
}

-- これは、壊れたメソッドが存在する 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;
    }
}

編集+

だから私はちょうど気づいた

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ではないため)?

4

1 に答える 1

7

Listではありません IteratorList を持ってい Iteratorます。List implements Iterable.

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

インスタンスを取得するiterator()には、を呼び出す必要があります。ListIterator

したがって、メソッドは読む必要があります

public Iterator<Entry> iterator(){
    List<Entry> iter = new LinkedList<Entry>();
    return iter.iterator();
}

に必ず電話iterator()してくださいList

implements Iterable<Entry>インターフェイスのジェネリック型パラメーターとして、クラスがメソッドIterableにエコーされることを確認してくださいinterface

編集

EntryOPの投稿されたクラスから、あなたinterfaceEntryiniterator()メソッドの間の混乱のように見えます。

Entryクラスはジェネリックで<K,V>あり、メソッドはまったくジェネリックではありません。

したがって、インターフェイスでは、メソッドが生またはメソッドからiterator返す必要があります。EntryEntry<?,?>iterator

おそらく、実装クラスはを実装し、メソッドの実装でEntry<K,V>を返しますIterator<Entry<K,V>>

これは の契約と互換性がありませんinterface

あなたのinterface方法は次のとおりです。

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

より一般的に:

  1. 独自のカスタム メソッドを追加するのではなく、interface拡張する必要があります。これにより、強化された for-each-loop を使用できます。Iterable<Entry<K,V>>
  2. スタイルの規則により、ジェネリック型パラメーターには 1 文字を使用するため、HashTableInterface<K,V>
  3. 使用しないpublicでくださいinterface-interfaceメソッドはpublicデフォルトで使用されるため、ノイズが追加されるだけです。

したがって、interfaceニーズを 2 つに分割すると、次のようになります。

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

編集 MK2

AList<Entry<K, V>>はaと同じではありませんList<TableEntry<K, V>>

私が最初に疑ったように、(紛らわしいことに) 2 つのEntryクラスがあり、1 つinterfaceは実装にネストされ、もう 1 つは実装にネストされています。

したがって、あなたの場合List<Entry<K, V>>は と同じではありませんList<Entry<K, V>>。混乱の原因がわかりますか?

あなたListは実装Entryであり、タイプのinterfaceが必要です。Entryinterface

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

を変更するListList<TableEntry<K, V>>、コードがコンパイルされないことに注意してください。

ここでの要点は、たとえこれが本当に良いアイデアのように思えても、決してクラスを同じものと呼ばないということです。

于 2013-04-13T15:01:53.457 に答える