programing

Java 8 스트림 역순서

itsource 2022. 7. 14. 20:57
반응형

Java 8 스트림 역순서

일반적인 질문:흐름을 되돌리는 적절한 방법은 무엇일까요?스트림이 어떤 요소로 구성되어 있는지 알 수 없다고 가정할 때 스트림을 되돌리는 일반적인 방법은 무엇입니까?

특정 질문:

IntStream 특정 생성 .IntStream.range(-range, 0)안 , 0으로 바꾸면 안 되고,으로 바꾸면 안 요.또한 사용할 수 없습니다.Integer::compare

List<Integer> list = Arrays.asList(1,2,3,4);
list.stream().sorted(Integer::compare).forEach(System.out::println);

IntStream 컴파일러

:(191, 0) ajc: " " "sorted()라고 하는 IntStream인수에 되지 않습니다(는 인수에 해당되지 않습니다.Integer::compare)

내가 뭘 놓쳤지?

에 관한 IntStream으로 해보세요

static IntStream revRange(int from, int to) {
    return IntStream.range(from, to)
                    .map(i -> to - i + from - 1);
}

이렇게 하면 복싱과 정렬을 피할 수 있습니다.

어떤 유형의 흐름을 되돌리는 방법에 대한 일반적인 질문에 대해서는 "적절한" 방법이 있는지 모르겠습니다.제가 생각할 수 있는 몇 가지 방법이 있습니다.둘 다 스트림 요소를 저장하게 됩니다.원소를 저장하지 않고 흐름을 되돌릴 수 있는 방법은 모르겠어요.

첫 번째 방법은 요소를 배열에 저장하고 스트림에 역순으로 읽어냅니다.스트림 요소의 런타임 유형을 모르기 때문에 어레이를 제대로 입력할 수 없으므로 체크되지 않은 캐스트가 필요합니다.

@SuppressWarnings("unchecked")
static <T> Stream<T> reverse(Stream<T> input) {
    Object[] temp = input.toArray();
    return (Stream<T>) IntStream.range(0, temp.length)
                                .mapToObj(i -> temp[temp.length - i - 1]);
}

또 다른 기술은 수집기를 사용하여 항목을 역목록에 누적합니다. 앞에 이 많이 .ArrayList복사도 많이 하고 있어요.

Stream<T> input = ... ;
List<T> output =
    input.collect(ArrayList::new,
                  (list, e) -> list.add(0, e),
                  (list1, list2) -> list1.addAll(0, list2));

커스터마이즈된 데이터 구조를 사용하여 훨씬 더 효율적인 반전 수집기를 작성할 수 있습니다.

업데이트 2016-01-29

이 조금 을 받았기 하기 위해 해야 할 것 .ArrayList이 방법은 많은 요소에서 O(N^2) 복사가 필요하기 때문에 매우 비효율적입니다.

&D를 사용하는 ArrayDeque대신 전면 삽입을 효율적으로 지원합니다. 약간 을 쓸 수 예요.Stream.collect()두을 첫 의 조작은 없습니다.Deque신,를 사용합니다addAll()첫 번째 arg의 내용을 두 번째 arg의 끝에 추가하고 두 번째 arg를 반환합니다. 위해서는 " " " 를 해야 합니다.Collector.of()공장법

완전한 코드는 다음과 같습니다.

Deque<String> output =
    input.collect(Collector.of(
        ArrayDeque::new,
        (deq, t) -> deq.addFirst(t),
        (d1, d2) -> { d2.addAll(d1); return d2; }));

결과, 「」가 됩니다.DequeList그러나, 이것은 큰 문제가 되지 않을 것입니다.그것은, 지금은 폐지된 순서로 간단하게 반복하거나 스트리밍 할 수 있기 때문입니다.

우아한 솔루션

List<Integer> list = Arrays.asList(1,2,3,4);
list.stream()
    .sorted(Collections.reverseOrder()) // Method on Stream<Integer>
    .forEach(System.out::println);

일반적인 질문:

스트림에는 요소가 저장되지 않습니다.

따라서 요소를 일부 중간 컬렉션에 저장하지 않으면 요소를 역순으로 반복할 수 없습니다.

Stream.of("1", "2", "20", "3")
      .collect(Collectors.toCollection(ArrayDeque::new)) // or LinkedList
      .descendingIterator()
      .forEachRemaining(System.out::println);

업데이트: Linked List를 ArrayDeque로 변경( 나은 기능)

인쇄:

3

20

2

1

런데, using using using를 sort정렬할 때 메서드가 올바르지 않고 반전되지 않음(스트림에 순서가 지정되지 않은 요소가 있을 수 있음)

특정 질문:

심플하고 쉽고 직관적인 (카피@Holger 코멘트)

IntStream.iterate(to - 1, i -> i - 1).limit(to - from)

에서는, 많은 방법이, 「 「정렬」을 반대로 하고 .IntStream단, 중간 스토리지가 불필요하게 필요합니다.Stuart Marks의 솔루션은 다음과 같습니다.

static IntStream revRange(int from, int to) {
    return IntStream.range(from, to).map(i -> to - i + from - 1);
}

이 테스트에 합격하여 오버플로도 올바르게 처리합니다.

@Test
public void testRevRange() {
    assertArrayEquals(revRange(0, 5).toArray(), new int[]{4, 3, 2, 1, 0});
    assertArrayEquals(revRange(-5, 0).toArray(), new int[]{-1, -2, -3, -4, -5});
    assertArrayEquals(revRange(1, 4).toArray(), new int[]{3, 2, 1});
    assertArrayEquals(revRange(0, 0).toArray(), new int[0]);
    assertArrayEquals(revRange(0, -1).toArray(), new int[0]);
    assertArrayEquals(revRange(MIN_VALUE, MIN_VALUE).toArray(), new int[0]);
    assertArrayEquals(revRange(MAX_VALUE, MAX_VALUE).toArray(), new int[0]);
    assertArrayEquals(revRange(MIN_VALUE, MIN_VALUE + 1).toArray(), new int[]{MIN_VALUE});
    assertArrayEquals(revRange(MAX_VALUE - 1, MAX_VALUE).toArray(), new int[]{MAX_VALUE - 1});
}

외부 lib가 없는 경우...

import java.util.List;
import java.util.Collections;
import java.util.stream.Collector;

public class MyCollectors {

    public static <T> Collector<T, ?, List<T>> toListReversed() {
        return Collectors.collectingAndThen(Collectors.toList(), l -> {
            Collections.reverse(l);
            return l;
        });
    }

}

하지 않는 방법:

  • 마세요.sorted(Comparator.reverseOrder()) ★★★★★★★★★★★★★★★★★」.sorted(Collections.reverseOrder())요소를 내림차순으로 정렬할 뿐이기 때문입니다.
    "CHANGE: "CHANGE: " 。
    [1, 4, 2, 5, 3]
    을 사용하다
    [5, 4, 3, 2, 1]
    다음 중 하나:
    ["A", "D", "B", "E", "C"]
    을 사용하다
    [E, D, C, B, A]
  • 마세요.sorted((a, b) -> -1) 설명

가장 쉬운 방법은 다음과 같습니다.

List<Integer> list = Arrays.asList(1, 4, 2, 5, 3);
Collections.reverse(list);
System.out.println(list);

★★★★★★
[3, 5, 2, 4, 1]

도 마찬가지입니다.String:

List<String> stringList = Arrays.asList("A", "D", "B", "E", "C");
Collections.reverse(stringList);
System.out.println(stringList);

★★★★★★
[C, E, B, D, A]

마세요.sorted((a, b) -> -1)!
가닥 병렬이 아닌 단일 스레드에서만 사용할 수 있습니다.
키키: :

(a, b) -> -1Comparator 달라집니다. 이것이 동작할지는 소트 알고리즘의 실장에 따라 달라집니다.JVM의 다음 릴리스에서는 이 문제가 해결될 수 있습니다.는 이 깰 수 요, 제로 、 음음 、 음음 、 음음 음음음 actually actually actually actually actually actually actually 。IntStream.range(0, 10000).parallel().boxed().sorted((a, b) -> -1).forEachOrdered(System.out::println);

//Don't use this!!!
List<Integer> list = Arrays.asList(1, 4, 2, 5, 3);
List<Integer> reversedList = list.stream()
        .sorted((a, b) -> -1)
        .collect(Collectors.toList());
System.out.println(reversedList);

"CHANGE: "CHANGE:
[3, 5, 2, 4, 1]

JVM은 다음과 같이 합니다.
[4, 1, 2, 3, 5]

도 마찬가지입니다.String:

//Don't use this!!!
List<String> stringList = Arrays.asList("A", "D", "B", "E", "C");
List<String> reversedStringList = stringList.stream()
        .sorted((a, b) -> -1)
        .collect(Collectors.toList());
System.out.println(reversedStringList);

"CHANGE: "CHANGE:
[C, E, B, D, A]

JVM은 다음과 같이 합니다.
[A, E, B, D, C]

요소를 역순으로 수집하는 자체 수집기를 정의할 수 있습니다.

public static <T> Collector<T, List<T>, List<T>> inReverse() {
    return Collector.of(
        ArrayList::new,
        (l, t) -> l.add(t),
        (l, r) -> {l.addAll(r); return l;},
        Lists::<T>reverse);
}

사용법은 다음과 같습니다.

stream.collect(inReverse()).forEach(t -> ...)

Array List를 사용하면 아이템을 효율적으로 수집할 수 있습니다(목록의 말미에).Guava Lists.reverse를 사용하면 다른 복사본을 만들지 않고도 목록을 효율적으로 반전 표시할 수 있습니다.

커스텀 컬렉터의 테스트 케이스는 다음과 같습니다.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

import org.hamcrest.Matchers;
import org.junit.Test;

import com.google.common.collect.Lists;

public class TestReverseCollector {
    private final Object t1 = new Object();
    private final Object t2 = new Object();
    private final Object t3 = new Object();
    private final Object t4 = new Object();

    private final Collector<Object, List<Object>, List<Object>> inReverse = inReverse();
    private final Supplier<List<Object>> supplier = inReverse.supplier();
    private final BiConsumer<List<Object>, Object> accumulator = inReverse.accumulator();
    private final Function<List<Object>, List<Object>> finisher = inReverse.finisher();
    private final BinaryOperator<List<Object>> combiner = inReverse.combiner();

    @Test public void associative() {
        final List<Object> a1 = supplier.get();
        accumulator.accept(a1, t1);
        accumulator.accept(a1, t2);
        final List<Object> r1 = finisher.apply(a1);

        final List<Object> a2 = supplier.get();
        accumulator.accept(a2, t1);
        final List<Object> a3 = supplier.get();
        accumulator.accept(a3, t2);
        final List<Object> r2 = finisher.apply(combiner.apply(a2, a3));

        assertThat(r1, Matchers.equalTo(r2));
    }

    @Test public void identity() {
        final List<Object> a1 = supplier.get();
        accumulator.accept(a1, t1);
        accumulator.accept(a1, t2);
        final List<Object> r1 = finisher.apply(a1);

        final List<Object> a2 = supplier.get();
        accumulator.accept(a2, t1);
        accumulator.accept(a2, t2);
        final List<Object> r2 = finisher.apply(combiner.apply(a2, supplier.get()));

        assertThat(r1, equalTo(r2));
    }

    @Test public void reversing() throws Exception {
        final List<Object> a2 = supplier.get();
        accumulator.accept(a2, t1);
        accumulator.accept(a2, t2);

        final List<Object> a3 = supplier.get();
        accumulator.accept(a3, t3);
        accumulator.accept(a3, t4);

        final List<Object> r2 = finisher.apply(combiner.apply(a2, a3));

        assertThat(r2, contains(t4, t3, t2, t1));
    }

    public static <T> Collector<T, List<T>, List<T>> inReverse() {
        return Collector.of(
            ArrayList::new,
            (l, t) -> l.add(t),
            (l, r) -> {l.addAll(r); return l;},
            Lists::<T>reverse);
    }
}

「」가 실장되어 있는 경우.Comparable<T>Integer,String,Date를 사용하면 .Comparator.reverseOrder().

List<Integer> list = Arrays.asList(1, 2, 3, 4);
list.stream()
     .sorted(Comparator.reverseOrder())
     .forEach(System.out::println);

cyclops-react Stream Utils에는 역스트림 메서드(javadoc)가 있습니다.

  StreamUtils.reverse(Stream.of("1", "2", "20", "3"))
             .forEach(System.out::println);

ArrayList에 수집한 후 ListIterator 클래스를 사용하여 어느 방향으로도 반복할 수 있으며 목록 상에서 거꾸로 반복할 수 있습니다.

리스트가 이미 있는 경우는, 보다 효율적입니다.

  StreamUtils.reversedStream(Arrays.asList("1", "2", "20", "3"))
             .forEach(System.out::println);

jOO,를 사용하는 것이 좋습니다.Java 8 스트림과 람다에 많은 유용한 기능을 추가할 수 있는 훌륭한 라이브러리입니다.

그런 다음 다음을 수행할 수 있습니다.

List<Integer> list = Arrays.asList(1,2,3,4);    
Seq.seq(list).reverse().forEach(System.out::println)

그렇게 간단하다.꽤 가벼운 라이브러리이므로 Java 8 프로젝트에 추가할 가치가 있습니다.

제가 생각해낸 솔루션은 다음과 같습니다.

private static final Comparator<Integer> BY_ASCENDING_ORDER = Integer::compare;
private static final Comparator<Integer> BY_DESCENDING_ORDER = BY_ASCENDING_ORDER.reversed();

그런 다음 대조군을 사용합니다.

IntStream.range(-range, 0).boxed().sorted(BY_DESCENDING_ORDER).forEach(// etc...

이 유틸리티 방법은 어떻습니까?

public static <T> Stream<T> getReverseStream(List<T> list) {
    final ListIterator<T> listIt = list.listIterator(list.size());
    final Iterator<T> reverseIterator = new Iterator<T>() {
        @Override
        public boolean hasNext() {
            return listIt.hasPrevious();
        }

        @Override
        public T next() {
            return listIt.previous();
        }
    };
    return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
            reverseIterator,
            Spliterator.ORDERED | Spliterator.IMMUTABLE), false);
}

중복 없이 모든 사건에서 효과가 있는 것 같아요

가장 간단한 방법(단순한 수집 - 병렬 스트림 지원):

public static <T> Stream<T> reverse(Stream<T> stream) {
    return stream
            .collect(Collector.of(
                    () -> new ArrayDeque<T>(),
                    ArrayDeque::addFirst,
                    (q1, q2) -> { q2.addAll(q1); return q2; })
            )
            .stream();
}

고급 방식(계속적인 방식으로 병렬 스트림을 지원):

public static <T> Stream<T> reverse(Stream<T> stream) {
    Objects.requireNonNull(stream, "stream");

    class ReverseSpliterator implements Spliterator<T> {
        private Spliterator<T> spliterator;
        private final Deque<T> deque = new ArrayDeque<>();

        private ReverseSpliterator(Spliterator<T> spliterator) {
            this.spliterator = spliterator;
        }

        @Override
        @SuppressWarnings({"StatementWithEmptyBody"})
        public boolean tryAdvance(Consumer<? super T> action) {
            while(spliterator.tryAdvance(deque::addFirst));
            if(!deque.isEmpty()) {
                action.accept(deque.remove());
                return true;
            }
            return false;
        }

        @Override
        public Spliterator<T> trySplit() {
            // After traveling started the spliterator don't contain elements!
            Spliterator<T> prev = spliterator.trySplit();
            if(prev == null) {
                return null;
            }

            Spliterator<T> me = spliterator;
            spliterator = prev;
            return new ReverseSpliterator(me);
        }

        @Override
        public long estimateSize() {
            return spliterator.estimateSize();
        }

        @Override
        public int characteristics() {
            return spliterator.characteristics();
        }

        @Override
        public Comparator<? super T> getComparator() {
            Comparator<? super T> comparator = spliterator.getComparator();
            return (comparator != null) ? comparator.reversed() : null;
        }

        @Override
        public void forEachRemaining(Consumer<? super T> action) {
            // Ensure that tryAdvance is called at least once
            if(!deque.isEmpty() || tryAdvance(action)) {
                deque.forEach(action);
            }
        }
    }

    return StreamSupport.stream(new ReverseSpliterator(stream.spliterator()), stream.isParallel());
}

다른 유형의 스트림(IntStream 등)으로 빠르게 확장할 수 있습니다.

테스트:

// Use parallel if you wish only
revert(Stream.of("One", "Two", "Three", "Four", "Five", "Six").parallel())
    .forEachOrdered(System.out::println);

결과:

Six
Five
Four
Three
Two
One

기타 주의사항:simplest way다른 스트림 연산과 함께 사용하면 그다지 유용하지 않습니다(콜렉트 조인(collect join)은 병렬 처리를 해제합니다).advance way예: 스트림의 초기 특성)을합니다.SORTED즉, 다른 스트림 작업과 함께 사용할 수 있는 방법입니다.

List newStream = list.stream().sorted(Collections.reverseOrder()).collect(Collectors.toList());
        newStream.forEach(System.out::println);

반대 순서로 요소를 수집하는 수집기를 쓸 수 있습니다.

public static <T> Collector<T, ?, Stream<T>> reversed() {
    return Collectors.collectingAndThen(Collectors.toList(), list -> {
        Collections.reverse(list);
        return list.stream();
    });
}

그리고 이렇게 사용하세요.

Stream.of(1, 2, 3, 4, 5).collect(reversed()).forEach(System.out::println);

원래 답변(버그 포함 - 병렬 스트림에서는 올바르게 작동하지 않음):

범용 스트림 리버스 방식은 다음과 같습니다.

public static <T> Stream<T> reverse(Stream<T> stream) {
    LinkedList<T> stack = new LinkedList<>();
    stream.forEach(stack::push);
    return stack.stream();
}

참고로 같은 문제를 보고 있었는데 스트림 요소의 문자열 값을 역순으로 결합하고 싶었습니다.

itemList = { last, middle, first } = > first, middle, last

중간 컬렉션을 사용하기 시작했습니다.collectingAndThencomonad 또는 the comonad에서ArrayDequeStuart Marks의 수집가, 비록 나는 중간 컬렉션에 만족하지 않았지만, 다시 스트리밍을 했다.

itemList.stream()
        .map(TheObject::toString)
        .collect(Collectors.collectingAndThen(Collectors.toList(),
                                              strings -> {
                                                      Collections.reverse(strings);
                                                      return strings;
                                              }))
        .stream()
        .collect(Collector.joining());

저는 마크스의 했습니다.Collector.of흥미로운 피니셔 람다가 있는 공장입니다.

itemList.stream()
        .collect(Collector.of(StringBuilder::new,
                             (sb, o) -> sb.insert(0, o),
                             (r1, r2) -> { r1.insert(0, r2); return r1; },
                             StringBuilder::toString));

하지 않기 는 그다지가 없기 에 저는 이 스트림을 사용하고 insert코드 정합성을 위해 어떤 문자열 빌더가 먼저 구축되느냐에 따라 달라지므로 상관없습니다.

Joiner를했는데 String Joiner가 .insert★★★★★★ 。

Java8뿐만 아니라 guava의 Lists.reverse() 메서드를 병용하면 다음과 같은 작업을 쉽게 수행할 수 있습니다.

List<Integer> list = Arrays.asList(1,2,3,4);
Lists.reverse(list).stream().forEach(System.out::println);

ArrayDequeLinkedList이다. "pushDeque"push()"Deque"의 앞부분에 합니다.

 protected <T> Stream<T> reverse(Stream<T> stream) {
    ArrayDeque<T> stack = new ArrayDeque<>();
    stream.forEach(stack::push);
    return stack.stream();
}

반전 문자열 또는 어레이

(Stream.of("abcdefghijklm 1234567".split("")).collect(Collectors.collectingAndThen(Collectors.toList(),list -> {Collections.reverse(list);return list;}))).stream().forEach(System.out::println);

분할은 구분자 또는 공간에 따라 수정할 수 있습니다.

에 관한 IntStream:

Java 9부터는의 3인수 버전을 사용할 수 있습니다.

IntStream.iterate(10, x -> x >= 0, x -> x - 1).forEach(System.out::println);

// Out: 10 9 8 7 6 5 4 3 2 1 0

여기서:

IntStream.iterate​(int seed, IntPredicate hasNext, IntUnaryOperator next);

  • seed 요소 - 초기 요소;
  • hasNext- 이 언제 되어야 하는지를 하기 위해 - 스트림의 종료 시기를 합니다.
  • next 이전 - 새로운 요소를 생성하기 위해 사용합니다.
How about reversing the Collection backing the stream prior?

import java.util.Collections;
import java.util.List;

public void reverseTest(List<Integer> sampleCollection) {
    Collections.reverse(sampleCollection); // remember this reverses the elements in the list, so if you want the original input collection to remain untouched clone it first.

    sampleCollection.stream().forEach(item -> {
      // you op here
    });
}

다음은 IntStream을 통한 전환에 대한 구체적인 질문에 대한 답변입니다.

IntStream.range(0, 10)
  .map(x -> x * -1)
  .sorted()
  .map(Math::abs)
  .forEach(System.out::println);

가장 간단한 해결책은 사용하는 것이다.List::listIterator ★★★★★★★★★★★★★★★★★」Stream::generate

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
ListIterator<Integer> listIterator = list.listIterator(list.size());

Stream.generate(listIterator::previous)
      .limit(list.size())
      .forEach(System.out::println);

이 메서드는 모든 스트림에서 동작하며 Java 8에 준거합니다.

Stream<Integer> myStream = Stream.of(1, 2, 3, 4, 5);
myStream.reduce(Stream.empty(),
        (Stream<Integer> a, Integer b) -> Stream.concat(Stream.of(b), a),
        (a, b) -> Stream.concat(b, a))
        .forEach(System.out::println);

이렇게 하는 거예요.

나는 새로운 컬렉션을 만들고 그것을 역방향으로 반복하는 아이디어가 마음에 들지 않는다.

IntStream #map 아이디어는 꽤 깔끔하지만, 저는 IntStream #반복 방식을 선호합니다.왜냐하면 제로까지의 카운트다운을 반복 방식으로 표현하고 어레이를 뒤에서 앞으로 걷는다는 점에서 이해하기 쉽기 때문입니다.

import static java.lang.Math.max;

private static final double EXACT_MATCH = 0d;

public static IntStream reverseStream(final int[] array) {
    return countdownFrom(array.length - 1).map(index -> array[index]);
}

public static DoubleStream reverseStream(final double[] array) {
    return countdownFrom(array.length - 1).mapToDouble(index -> array[index]);
}

public static <T> Stream<T> reverseStream(final T[] array) {
    return countdownFrom(array.length - 1).mapToObj(index -> array[index]);
}

public static IntStream countdownFrom(final int top) {
    return IntStream.iterate(top, t -> t - 1).limit(max(0, (long) top + 1));
}

동작하는 것을 증명하는 테스트는 다음과 같습니다.

import static java.lang.Integer.MAX_VALUE;
import static org.junit.Assert.*;

@Test
public void testReverseStream_emptyArrayCreatesEmptyStream() {
    Assert.assertEquals(0, reverseStream(new double[0]).count());
}

@Test
public void testReverseStream_singleElementCreatesSingleElementStream() {
    Assert.assertEquals(1, reverseStream(new double[1]).count());
    final double[] singleElementArray = new double[] { 123.4 };
    assertArrayEquals(singleElementArray, reverseStream(singleElementArray).toArray(), EXACT_MATCH);
}

@Test
public void testReverseStream_multipleElementsAreStreamedInReversedOrder() {
    final double[] arr = new double[] { 1d, 2d, 3d };
    final double[] revArr = new double[] { 3d, 2d, 1d };
    Assert.assertEquals(arr.length, reverseStream(arr).count());
    Assert.assertArrayEquals(revArr, reverseStream(arr).toArray(), EXACT_MATCH);
}

@Test
public void testCountdownFrom_returnsAllElementsFromTopToZeroInReverseOrder() {
    assertArrayEquals(new int[] { 4, 3, 2, 1, 0 }, countdownFrom(4).toArray());
}

@Test
public void testCountdownFrom_countingDownStartingWithZeroOutputsTheNumberZero() {
    assertArrayEquals(new int[] { 0 }, countdownFrom(0).toArray());
}

@Test
public void testCountdownFrom_doesNotChokeOnIntegerMaxValue() {
    assertEquals(true, countdownFrom(MAX_VALUE).anyMatch(x -> x == MAX_VALUE));
}

@Test
public void testCountdownFrom_givesZeroLengthCountForNegativeValues() {
    assertArrayEquals(new int[0], countdownFrom(-1).toArray());
    assertArrayEquals(new int[0], countdownFrom(-4).toArray());
}

이 모든 것에서 나는 내가 먼저 할 대답을 보지 못한다.

이것은 질문에 대한 직접적인 답변은 아니지만 잠재적인 해결책입니다.

애초에 목록을 거꾸로 작성하기만 하면 됩니다.가능하면 ArrayList 대신 LinkedList를 사용하고 항목을 추가할 때는 add 대신 Push를 사용합니다.리스트는 역순으로 작성되어 조작 없이 올바르게 스트리밍됩니다.

이는 이미 다양한 방법으로 사용되고 있지만 의외로 많은 경우에 잘 작동하는 원시 어레이나 목록을 다루는 경우에는 적합하지 않습니다.

캐스팅 없이 @stuart-marks의 답변에 따라 목록 요소의 스트림을 끝에서 반환하는 함수:

public static <T> Stream<T> reversedStream(List<T> tList) {
    final int size = tList.size();
    return IntStream.range(0, size)
            .mapToObj(i -> tList.get(size - 1 - i));
}

// usage
reversedStream(list).forEach(System.out::println);

What's the proper generic way to reverse a stream?

스트림이 조우 순서를 지정하지 않으면 지정하지 마십시오.(!s.spliterator().hasCharacteristics(java.util.Spliterator.ORDERED))

목록을 되돌리는 가장 일반적이고 쉬운 방법은 다음과 같습니다.

public static <T> void reverseHelper(List<T> li){

 li.stream()
.sorted((x,y)-> -1)
.collect(Collectors.toList())
.forEach(System.out::println);

    }

Java 8의 방법:

    List<Integer> list = Arrays.asList(1,2,3,4);
    Comparator<Integer> comparator = Integer::compare;
    list.stream().sorted(comparator.reversed()).forEach(System.out::println);

언급URL : https://stackoverflow.com/questions/24010109/java-8-stream-reverse-order

반응형