4

あるクラスのジェネリック型が、パラメーターとして渡される別のオブジェクトのジェネリック型によって定義される可能性があるのだろうか?

私が取り組んでいるのはスレッドセーフなイテレータです。そのため、複数のスレッドがリストを安全にイテレータでき、2 つのスレッドが同じオブジェクトを取得することはありません。今の形でも十分に機能しますが、もう少し良くできると思います。

import java.util.Iterator;
public class AtomicIterator implements Iterator<Object>
{
    private Iterator<?> it;

    public AtomicIterator(Iterable<?> iterable)
    {
        it = iterable.iterator();
    }

    public Object next()
    {
        synchronized(it)
        {
            if(it.hasNext())
                return it.next();
            else
                return null;
        }
    }
}

一部のコードは省略されていますが、これでアイデアが伝わるはずです。現在、次のオブジェクトを取得するには、返されたオブジェクトを常にキャストする必要がありますが、これは非効率的です。

ArrayList<String> someList = new ArrayList<String>;
AtomicIterator it = new AtomicIterator(someList);
String example = (String)it.next();

問題は明らかに、この例では型を返すために、必要な場所にit.next()型を返すことですObjectString

簡単な解決策は、AtomicIterator独自のジェネリック型を指定して、次のようにすることです

ArrayList<String> someList = new ArrayList<String>();
AtomicIterator<String> it = new AtomicIterator<String>(someList);
String example = it.next();

ただし、これは私にsomeListは冗長に思えます。明示的に定義されたジェネリック型があり、与えられたオブジェクトからジェネリック型を推測しStringたいのです。AtomicIteratorIterable

私が本当に欲しいのは、このようなものです

import java.util.Iterator;
public class AtomicIterator implements Iterator<E>
{
    private Iterator<E> it;

    public <E> AtomicIterator(Iterable<E> iterable)
    {
        it = iterable.iterator();
    }

    public E next()
    {
        synchronized(it)
        {
            if(it.hasNext())
                return it.next();
            else
                return null;
        }
    }
}

そして、そこから次のようなことができます

ArrayList<String> someList = new ArrayList<String>();
AtomicIterator it = new AtomicIterator(someList);
String example = it.next();

しかし残念ながら、ジェネリック型Eはコンストラクターのスコープ内にしか存在しないため、これは機能しません。

これを行うためのきれいな方法を知っている人はいますか?

4

3 に答える 3

6

ジェネリック型を AtomicIterator に追加し、(Java 6 で実行している場合は) 静的ファクトリ メソッドを追加して、デフォルトでジェネリック型を解決します。

public class AtomicIterator<T> implements Iterator<T>
{
    private Iterator<T> it;

    public AtomicIterator(Iterable<T> iterable)
    {
        it = iterable.iterator();
    }

    public static <T> AtomicIterator<T> create ( Iterable<T> iterable )
    {
        return new AtomicIterator( iterable )
    }

    public T next()
    {
        synchronized(it)
        {
            if(it.hasNext())
                return it.next();
            else
                return null;
        }
    }
}

使用法は次のとおりです。

ArrayList<String> someList = new ArrayList<String>;
AtomicIterator<String> it = AtomicIterator.create(someList);
于 2013-04-04T21:00:06.423 に答える
0

Java 7 ダイヤモンド推論 -

AtomicIterator<String> it = new AtomicIterator<>(someList); 
                                               ^ 
                                               no need to repeat String here


public class AtomicIterator<E> implements Iterator<E>

    public AtomicIterator(Iterable<E> iterable)

の完全な型を明示的に記述したくない場合はit、代わりに、コンパイラに型を推測させます。

var it = new ...;   // the type of `it` is inferred from right hand side

残念ながら、Java にはまだその機能がなく、しばらくはありません。

于 2013-04-04T21:21:29.600 に答える