[SCALA] 자바 8 스트림 API와 정수의 목록을 셔플
SCALA자바 8 스트림 API와 정수의 목록을 셔플
나는 스트림 API를 사용하여 Java 8 스칼라의 다음 줄을 번역하려고 :
// Scala
util.Random.shuffle((1 to 24).toList)
내가 정수의 범위를 만든 자바에서 동등한를 작성하려면 :
IntStream.range(1, 25)
나는 스트림 API에 toList 방법을 찾기 위해 의심하지만, IntStream 만 이상한 방법을 알고있다 :
collect(
Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R,R> combiner)
어떻게 자바 8 스트림 API를 사용하여 목록을 셔플 할 수 있습니까?
해결법
-
==============================
1.여기 가서 :
여기 가서 :
List<Integer> integers = IntStream.range(1, 10) // <-- creates a stream of ints .boxed() // <-- converts them to Integers .collect(Collectors.toList()); // <-- collects the values to a list Collections.shuffle(integers); System.out.println(integers);
인쇄물:
[8, 1, 5, 3, 4, 2, 6, 9, 7]
-
==============================
2.다음 toShuffledList () 메소드가 유용 할 수있다.
다음 toShuffledList () 메소드가 유용 할 수있다.
private static final Collector<?, ?, ?> SHUFFLER = Collectors.collectingAndThen( Collectors.toCollection(ArrayList::new), list -> { Collections.shuffle(list); return list; } ); @SuppressWarnings("unchecked") public static <T> Collector<T, ?, List<T>> toShuffledList() { return (Collector<T, ?, List<T>>) SHUFFLER; }
이 한 줄의 다음과 같은 종류의 수 있습니다 :
IntStream.rangeClosed('A', 'Z') .mapToObj(a -> (char) a) .collect(toShuffledList()) .forEach(System.out::print);
출력 예 :
AVBFYXIMUDENOTHCRJKWGQZSPL
-
==============================
3.당신은 사용자 정의 비교기를 사용할 수있는 "종류"임의의 값으로 값 :
당신은 사용자 정의 비교기를 사용할 수있는 "종류"임의의 값으로 값 :
public final class RandomComparator<T> implements Comparator<T> { private final Map<T, Integer> map = new IdentityHashMap<>(); private final Random random; public RandomComparator() { this(new Random()); } public RandomComparator(Random random) { this.random = random; } @Override public int compare(T t1, T t2) { return Integer.compare(valueFor(t1), valueFor(t2)); } private int valueFor(T t) { synchronized (map) { return map.computeIfAbsent(t, ignore -> random.nextInt()); } } }
스트림의 각 개체는에 우리 일종의 임의의 정수 값을, 연관 (느리게)입니다. 지도에 동기화는 병렬 스트림을 처리하는 것입니다.
그런 다음처럼 사용할 수 있습니다 :
IntStream.rangeClosed(0, 24).boxed() .sorted(new RandomComparator<>()) .collect(Collectors.toList());
이 솔루션의 장점은 스트림 파이프 라인 내에서 통합되어 있다는 것입니다.
-
==============================
4.셔플을 수행하려면 효율적으로 사전에 모든 값이 필요합니다. 당신이 스칼라처럼 당신이 목록에 스트림을 변환 한 후에는 Collections.shuffle ()를 사용할 수 있습니다.
셔플을 수행하려면 효율적으로 사전에 모든 값이 필요합니다. 당신이 스칼라처럼 당신이 목록에 스트림을 변환 한 후에는 Collections.shuffle ()를 사용할 수 있습니다.
-
==============================
5.당신은 너무 많은 번거 로움없이 전체 스트림을 처리하려면, 당신은 단순히 Collectors.collectingAndThen ()를 사용하여 자신의 수집기를 만들 수 있습니다 :
당신은 너무 많은 번거 로움없이 전체 스트림을 처리하려면, 당신은 단순히 Collectors.collectingAndThen ()를 사용하여 자신의 수집기를 만들 수 있습니다 :
public static <T> Collector<T, ?, Stream<T>> toEagerShuffledStream() { return Collectors.collectingAndThen( toList(), list -> { Collections.shuffle(list); return list.stream(); }); }
당신은 (제한하려면하지만이) 잘 결과 스트림을 수행하지 않습니다. 이 문제를 극복하기 위해, 하나는 사용자 정의 Spliterator를 만들 수 있습니다 :
package com.pivovarit.stream; import java.util.List; import java.util.Random; import java.util.Spliterator; import java.util.function.Consumer; import java.util.function.Supplier; public class ImprovedRandomSpliterator<T> implements Spliterator<T> { private final Random random; private final T[] source; private int size; ImprovedRandomSpliterator(List<T> source, Supplier<? extends Random> random) { if (source.isEmpty()) { throw new IllegalArgumentException("RandomSpliterator can't be initialized with an empty collection"); } this.source = (T[]) source.toArray(); this.random = random.get(); this.size = this.source.length; } @Override public boolean tryAdvance(Consumer<? super T> action) { int nextIdx = random.nextInt(size); int lastIdx = size - 1; action.accept(source[nextIdx]); source[nextIdx] = source[lastIdx]; source[lastIdx] = null; // let object be GCed return --size > 0; } @Override public Spliterator<T> trySplit() { return null; } @Override public long estimateSize() { return source.length; } @Override public int characteristics() { return SIZED; } }
그리고:
public final class RandomCollectors { private RandomCollectors() { } public static <T> Collector<T, ?, Stream<T>> toImprovedLazyShuffledStream() { return Collectors.collectingAndThen( toCollection(ArrayList::new), list -> !list.isEmpty() ? StreamSupport.stream(new ImprovedRandomSpliterator<>(list, Random::new), false) : Stream.empty()); } public static <T> Collector<T, ?, Stream<T>> toEagerShuffledStream() { return Collectors.collectingAndThen( toCollection(ArrayList::new), list -> { Collections.shuffle(list); return list.stream(); }); } }
내가 여기에 성능 고려 사항을 설명했다 https://4comprehension.com/implementing-a-randomized-stream-spliterator-in-java/
-
==============================
6.당신이 찾고있는 경우 "임의의"주문 대 용액과 결정, 단순히 "우연"주문 "만 스트리밍"충분히 좋은이며, 할 수 있습니다 항상 일종의 해시 값만큼의 int :
당신이 찾고있는 경우 "임의의"주문 대 용액과 결정, 단순히 "우연"주문 "만 스트리밍"충분히 좋은이며, 할 수 있습니다 항상 일종의 해시 값만큼의 int :
List<Integer> xs=IntStream.range(0, 10) .boxed() .sorted( (a, b) -> a.hashCode() - b.hashCode() ) .collect(Collectors.toList());
당신이 오히려 목록 <정수>보다 지능 []이 원하는 경우, 당신은 나중에 그들을 언 박싱 수 있습니다. 불행하게도, 당신은 그래서 과정의 일부가 제거있어, 사용자 지정 비교기를 적용 할 권투 단계를 통과 없었다.
List<Integer> ys=IntStream.range(0, 10) .boxed() .sorted( (a, b) -> a.hashCode() - b.hashCode() ) .mapToInt( a -> a.intValue()) .toArray();
-
==============================
7.
public static List<Integer> getSortedInRandomOrder(List<Integer> list) { return list .stream() .sorted((o1, o2) -> ThreadLocalRandom.current().nextInt(-1, 2)) .collect(Collectors.toList()); }
-
==============================
8.이것은 내 하나의 라인 솔루션입니다 : 나는 1 개 임의의 색상을 따기입니다 :
이것은 내 하나의 라인 솔루션입니다 : 나는 1 개 임의의 색상을 따기입니다 :
colourRepository.findAll().stream().sorted((o1,o2)-> RandomUtils.nextInt(-1,1)).findFirst().get()
from https://stackoverflow.com/questions/20058366/shuffle-a-list-of-integers-with-java-8-streams-api by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 두 목록의 직교 제품 (0) | 2019.11.09 |
---|---|
[SCALA] 자바 8 스트림, 점점 머리와 꼬리 (0) | 2019.11.09 |
[SCALA] 스칼라에서 제네릭 형식에 대한 패턴 매칭 (0) | 2019.11.09 |
[SCALA] 왜`배열 (0,1,2) == 배열 (0,1,2)`예상 된 결과를 반환하지 않습니다? (0) | 2019.11.09 |
[SCALA] 소스가 Source.actorRef에서 만든 akka 스트림의 기본 ActorRef 액세스 (0) | 2019.11.09 |