パラメータ化された型の空のコレクションに対するJavaイテレータ

StackOverflow https://stackoverflow.com/questions/821536

  •  03-07-2019
  •  | 
  •  

質問

Javaでは、メソッドからイテレータを返す必要があります。私のデータは別のオブジェクトから取得されるので、通常はイテレーターを提供できるので、それを返すことができますが、状況によっては基礎となるデータがnullになります。一貫性を保つために、<!> quot; empty <!> quot;を返します。その場合、イテレータを使用するため、呼び出し元はnullをテストする必要がありません。

次のようなものを書きたかった:

public Iterator<Foo> iterator() {
   if (underlyingData != null) {
      return underlyingData.iterator();  // works
   } else {
      return Collections.emptyList().iterator();  // compiler error
   }
}

しかし、Javaコンパイラは、Iterator<Object>ではなくIterator<Foo>を返すことについて文句を言います。 (Iterator<Foo>)へのキャストも機能しません。

役に立ちましたか?

解決

次の構文を使用して、Foo型の空のリストを取得できます。

return Collections.<Foo>emptyList().iterator();

他のヒント

Java 7は長い間使用されていません。以前のJavaバージョン用に開発している場合を除き、次のような空のイテレーターを返します。

return Collections.emptyIterator();

次の行に沿ってもっと行きたいです

public Iterator<Foo> iterator() {
    if (underlyingData == null)
        return Collections.<Foo> emptyList().iterator();
    return underlyingData.iterator();
}

特別なケースを処理して戻り、通常のケースを処理します。しかし、私の主なポイントは、割り当てを回避できることです

Collections.<Foo> emptyList().iterator();

Collections.<Foo>emptyList().iterator()の迷惑が google-collections Iterators.emptyIterator()を提供する主な理由です。あなたのような場合、型パラメータは必要ありません。

これは、Javaの型推論がすべての場合に機能するわけではなく、三項演算子が明らかに同等のif-else構造と必ずしも同等ではないことを示していると思います。

避けるnull も述べたい。また、Iteratorを渡すことも避けてください。奇妙なステートフル動作を持っているためです(Iterableを優先)。ただし、これを行うための正当な、時期尚早な理由があると仮定すると、それを書くための私の好ましい方法は

public Iterator<Foo> iterator() {
    return getUnderlyingData().iterator();
}
private List<Foo> getUnderlyingData() {
    if (underlyingData == null) {
        return Collections.emptyList();
    } else {
        return underlyingData;
    }
}

IMO、推測可能な型情報を推論できる場合は挿入する方が良い(コードが長くなる場合でも)。

ほぼ確実に複数回実行するため、ローカル変数を宣言するだけでなく、getUnderlyingDataメソッドを挿入します。

両方の結果でiteratorを呼び出しているので、繰り返してはいけません。

すみません、わかりました。コンパイラーがパラメーター化された型を判別できるように、割り当てを使用する必要があります。

public Iterator<Foo> iterator() {
   if (underlyingData != null) {
      return underlyingData.iterator();
   } else {
      List<Foo> empty = Collections.emptyList();  // param type inference
      return empty.iterator();
   }
}
public  final class EmptyIterator{

    public static Iterator iterator(){
        return new Empty();
    }

    private static class Empty implements Iterator {
        public boolean hasNext(){
            return false;
        }
        public Object next(){
            throw new NoSuchElementException();
        }
        public void remove(){
        }
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top