回答:
import com.google.common.collect.Lists;
Iterator<Element> myIterator = ... //some iterator
List<Element> myList = Lists.newArrayList(myIterator);
別のグアバの例:
ImmutableList.copyOf(myIterator);
import org.apache.commons.collections.IteratorUtils;
Iterator<Element> myIterator = ...//some iterator
List<Element> myList = IteratorUtils.toList(myIterator);
Java 8ではforEachRemaining
、Iterator
インターフェースに追加された新しいメソッドを使用できます。
List<Element> list = new ArrayList<>();
iterator.forEachRemaining(list::add);
::
?なんて名前?list.add();への直接参照のようです また、java8の新しいものもあるようです。ありがとう!:)
::
構文はJava 8で新しくなり、ラムダの省略形である「メソッド参照」を参照します。詳細については、こちらを参照してください:docs.oracle.com/javase/tutorial/java/javaOO/…–
iterator
から来たの?それは未解決のシンボルです
iterator
。
次のように、イテレータを新しいリストにコピーできます。
Iterator<String> iter = list.iterator();
List<String> copy = new ArrayList<String>();
while (iter.hasNext())
copy.add(iter.next());
これは、リストに文字列が含まれていることを前提としています。イテレータからリストを再作成するより速い方法は実際にはありません。手作業でリストをトラバースし、各要素を適切なタイプの新しいリストにコピーするのに悩まされています。
編集:
タイプセーフな方法でイテレータを新しいリストにコピーする一般的な方法を次に示します。
public static <T> List<T> copyIterator(Iterator<T> iter) {
List<T> copy = new ArrayList<T>();
while (iter.hasNext())
copy.add(iter.next());
return copy;
}
次のように使用します。
List<String> list = Arrays.asList("1", "2", "3");
Iterator<String> iter = list.iterator();
List<String> copy = copyIterator(iter);
System.out.println(copy);
> [1, 2, 3]
がある場合Iterable
、Java 8ではこのソリューションを使用できます。
Iterable<Element> iterable = createIterable();
List<Element> array = StreamSupport
.stream(iterable.spliterator(), false)
.collect(Collectors.toList());
私が知っているようにインスタンスをCollectors.toList()
作成しArrayList
ます。
実は私の意見では、一行で見栄えも良いです。
たとえばList<Element>
、いくつかのメソッドから戻る必要がある場合:
return StreamSupport.stream(iter.spliterator(), false).collect(Collectors.toList());
Iterable
iterator
。それらは完全に異なります。
Iterator
、簡単に使い捨てに 戻すことができます。これは、このような状況で役立ちますが、重要なことをもう一度強調しておきます。この方法は、1 回の使用で問題ない場合にのみ使用できます。複数回呼び出すと、予期しない結果が生じます。上記の答えは、次のようになりますIterable
() -> iterator
Iterable
iterable.iterator()
Iterator<Element> iterator = createIterator();
List<Element> array = StreamSupport.stream(((Iterable<Element>) () -> iterable).spliterator(), false).collect(toList());
ジェネリックはサポートしていませんが、IteratorUtils
Apache commons-collectionsからも使用できます。
List list = IteratorUtils.toList(iterator);
を使用したプレーンJava 8によるかなり簡潔なソリューションjava.util.stream
:
public static <T> ArrayList<T> toArrayList(final Iterator<T> iterator) {
return StreamSupport
.stream(
Spliterators
.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false)
.collect(
Collectors.toCollection(ArrayList::new)
);
}
iterator.forEachRemaining( list::add )
また、新しいJava 8で、多くのより簡潔です。リスト変数をにCollector
プッシュしても、a Stream
とaでサポートされる必要があるため、この場合の読みやすさは向上しませんSpliterator
。
List result = new ArrayList();
while (i.hasNext()){
result.add(i.next());
}
Iterable
!=Iterator
私は、一見明白な解決策を指摘したいしません仕事を:
リストリスト= Stream.generate(iterator :: next) .collect(Collectors.toList());
これStream#generate(Supplier<T>)
は、無限のストリームしか作成できないためで、その引数がスローすることを期待していませんNoSuchElementException
(それIterator#next()
が最終的に何をするかです)。
イテレーター→ストリーム→リストの方法を選択する場合は、代わりにxehpukの回答を使用する必要があります。
グーグルグアバを使用してください!
Iterable<String> fieldsIterable = ...
List<String> fields = Lists.newArrayList(fieldsIterable);
++
ここで、この場合、可能な限り最速の方法が必要な場合for loop
は、その方が適しています。
ループのテイクは10,000 runs
テイクのサンプルサイズのイテレータ40 ms
2 ms
ArrayList<String> alist = new ArrayList<String>();
long start, end;
for (int i = 0; i < 1000000; i++) {
alist.add(String.valueOf(i));
}
ListIterator<String> it = alist.listIterator();
start = System.currentTimeMillis();
while (it.hasNext()) {
String s = it.next();
}
end = System.currentTimeMillis();
System.out.println("Iterator start: " + start + ", end: " + end + ", delta: "
+ (end - start));
start = System.currentTimeMillis();
int ixx = 0;
for (int i = 0; i < 100000; i++) {
String s = alist.get(i);
}
System.out.println(ixx);
end = System.currentTimeMillis();
System.out.println("for loop start: " + start + ", end: " + end + ", delta: "
+ (end - start));
これは、リストに文字列が含まれていることを前提としています。
for
ループを使用してリストの要素にアクセスするget(i)
方がイテレータを使用するよりも高速です...しかし、それはOPが求めていることではなく、イテレータが入力として与えられると具体的に述べました。
get(int)
ループあなただけの1メートルエントリの100Kを見ています。そのループを次のように変更it.size()
すると、これらの2つの方法がほぼ同じ速度であることがわかります。一般に、これらの種類のJava速度テストは、実際のパフォーマンス情報が限られているため、懐疑的に見る必要があります。