Reversing Streams in Java: Generic and Specific Approaches
When dealing with Java streams, understanding how to reverse them can be crucial. Let's delve into the specific and generic approaches for reversing streams.
Specific Approach: Reversing an IntStream
To reverse an IntStream while maintaining its range, you can utilize the following approach:
<code class="java">static IntStream revRange(int from, int to) { return IntStream.range(from, to) .map(i -> to - i + from - 1); }</code>
This method avoids unnecessary boxing and sorting operations.
Generic Approach: Reversing a Stream of Any Type
For streams of arbitrary types, there's currently no predefined "proper" way to reverse them. However, here are two common options:
1. Reversing Using Array:
This method stores the stream elements in an array and retrieves them in reverse order:
<code class="java">@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]); }</code>
2. Reversing Using Collector:
This method uses a collector to accumulate elements in a reversed list:
<code class="java">Stream<T> input = ... ; List<T> output = input.collect(ArrayList::new, (list, e) -> list.add(0, e), (list1, list2) -> list1.addAll(0, list2));</code>
Efficient Reversal Using ArrayDeque
Due to its O(N^2) copying inefficiency, we update our previous code using an ArrayDeque for more efficient insertion at the front:
<code class="java">Deque<String> output = input.collect(Collector.of( ArrayDeque::new, (deq, t) -> deq.addFirst(t), (d1, d2) -> { d2.addAll(d1); return d2; }));</code>
This method produces a reversed Deque, which can be easily converted back into a Stream or iterated directly.
The above is the detailed content of How to Reverse Streams in Java: Specific and Generic Approaches?. For more information, please follow other related articles on the PHP Chinese website!