답변:
구아바 와 같은 라이브러리를 더 잘 사용하십시오 .
import com.google.common.collect.Lists;
Iterator<Element> myIterator = ... //some iterator
List<Element> myList = Lists.newArrayList(myIterator);
다른 구아바 예 :
ImmutableList.copyOf(myIterator);
또는 Apache Commons 컬렉션 :
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
와 (과 )의 차이점이 Iterator
있습니다.
당신이있는 경우 Iterable
, 다음 자바 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
A와 다시 하나의 사용을 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 )
또한 새로운 자바 8, 훨씬 더 간결. Collector
이 경우 리스트 변수를 푸시 해도 가독성이 향상되지 않습니다 . a Stream
및 a 가 지원해야하기 때문 Spliterator
입니다.
List result = new ArrayList();
while (i.hasNext()){
result.add(i.next());
}
나는 작동 하지 않을 것처럼 보이는 명백한 해결책을 지적하고 싶습니다 .
목록 목록 = Stream.generate (iterator :: next) .collect (Collectors.toList ());
Stream#generate(Supplier<T>)
무한 스트림 만 만들 수 있기 때문에 인수가 발생할 것으로 기대하지 않습니다 NoSuchElementException
( Iterator#next()
결국 수행 할 작업).
Iterator → Stream → List 방식을 선택하는 경우 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)
루프 에서는 1m 항목 중 100k 만보고 있습니다. 루프를 변경 it.size()
하면이 두 가지 방법이 같은 속도에 가깝다는 것을 알 수 있습니다. 일반적으로 이러한 종류의 Java 속도 테스트는 제한된 실제 성능 정보를 제공하며 회의적으로 살펴 봐야합니다.