web-dev-qa-db-ja.com

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

Javaでは、メソッドからイテレータを返す必要があります。私のデータは、通常はイテレータを提供できる別のオブジェクトから取得されているため、それを返すことができますが、状況によっては、基になるデータがnullになります。一貫性を保つために、その場合は「空の」イテレータを返したいので、呼び出し元は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>)へのキャストも機能しません。

29
miner49r

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

return Collections.<Foo>emptyList().iterator();
59
Alex B

Java7は長い間リリースされています。以前のJavaバージョン用に開発しているのでない限り、次のような空のイテレータを返します。

return Collections.emptyIterator();
27
GOTO 0

私はもっ​​と行きます

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

ただ、特別な場合を処理して戻り、次に通常の場合を処理します。しかし、私の主なポイントは、あなたが割り当てを回避できるということです

Collections.<Foo> emptyList().iterator();
9
Carl Manaster

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

4

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

また、次のように述べたいと思いますnullは避けてください。また、Iteratorsは奇妙なステートフル動作をするため、渡さないでください(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();
   }
}
0
miner49r
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(){
        }
    }
}
0
abhay8nitt