다음을 수행하고 싶습니다.
List<Integer> list = IntStream.range(0, 7).collect(Collectors.toList());
그러나 결과 목록은 Guava의 ImmutableList
.
내가 할 수 있다는 걸 알아
List<Integer> list = IntStream.range(0, 7).collect(Collectors.toList());
List<Integer> immutableList = ImmutableList.copyOf(list);
하지만 직접 수집하고 싶습니다. 난 노력 했어
List<Integer> list = IntStream.range(0, 7)
.collect(Collectors.toCollection(ImmutableList::of));
하지만 예외가 발생했습니다.
com.google.common.collect.ImmutableCollection.add (ImmutableCollection.java:96)의 java.lang.UnsupportedOperationException
답변
답변
collectingAndThen
수집기가 유용한 곳은 다음과 같습니다.
List<Integer> list = IntStream.range(0, 7).boxed()
.collect(collectingAndThen(toList(), ImmutableList::copyOf));
List
방금 구축 한 변형을 적용합니다 . 결과는 ImmutableList
.
또는에 직접 모아서 마지막에 Builder
전화 할 수 있습니다 build()
.
List<Integer> list = IntStream.range(0, 7)
.collect(Builder<Integer>::new, Builder<Integer>::add, (builder1, builder2) -> builder1.addAll(builder2.build()))
.build();
이 옵션이 다소 장황하고 여러 곳에서 사용하려는 경우 고유 한 수집기를 만들 수 있습니다.
class ImmutableListCollector<T> implements Collector<T, Builder<T>, ImmutableList<T>> {
@Override
public Supplier<Builder<T>> supplier() {
return Builder::new;
}
@Override
public BiConsumer<Builder<T>, T> accumulator() {
return (b, e) -> b.add(e);
}
@Override
public BinaryOperator<Builder<T>> combiner() {
return (b1, b2) -> b1.addAll(b2.build());
}
@Override
public Function<Builder<T>, ImmutableList<T>> finisher() {
return Builder::build;
}
@Override
public Set<Characteristics> characteristics() {
return ImmutableSet.of();
}
}
그리고:
List<Integer> list = IntStream.range(0, 7)
.boxed()
.collect(new ImmutableListCollector<>());
댓글에서 링크가 사라지는 경우를 대비하여 내 두 번째 접근 방식은 단순히 Collector.of
. 자신 만의 Collector
수업을 만드는 것보다 간단합니다 .
public static <T> Collector<T, Builder<T>, ImmutableList<T>> toImmutableList() {
return Collector.of(Builder<T>::new, Builder<T>::add, (l, r) -> l.addAll(r.build()), Builder<T>::build);
}
및 사용법 :
List<Integer> list = IntStream.range(0, 7)
.boxed()
.collect(toImmutableList());
답변
내 질문에 대한 직접적인 대답은 아니지만 (컬렉터를 사용하지 않음) 중간 컬렉션을 사용하지 않는 상당히 우아한 접근 방식입니다.
Stream<Integer> stream = IntStream.range(0, 7).boxed();
List<Integer> list = ImmutableList.copyOf(stream.iterator());
소스 .
답변
BTW : JDK 10 이후 순수 Java로 수행 할 수 있습니다.
List<Integer> list = IntStream.range(0, 7)
.collect(Collectors.toUnmodifiableList());
또한 toUnmodifiableSet
및 toUnmodifiableMap
가능합니다.
내부 수집기는 다음을 통해 수행되었습니다. List.of(list.toArray())
답변
참고로 Java 8없이 Guava에서이 작업을 수행하는 합리적인 방법이 있습니다.
ImmutableSortedSet<Integer> set = ContiguousSet.create(
Range.closedOpen(0, 7), DiscreteDomain.integers());
ImmutableList<Integer> list = set.asList();
List
의미론이 실제로 필요하지 않고를 사용할 수 있다면 NavigableSet
a ContiguousSet
가 실제로 모든 요소를 저장할 필요가 없기 때문에 훨씬 좋습니다 ( Range
및 DiscreteDomain
).