Bunun tersini oluşturma sorusu için şöyle bir IntStream
şey deneyin:
static IntStream revRange(int from, int to) {
return IntStream.range(from, to)
.map(i -> to - i + from - 1);
}
Bu boks ve ayıklamayı önler.
Herhangi bir türdeki bir akışı nasıl tersine çevireceğimize dair genel soru için, "uygun" bir yol olduğunu bilmiyorum. Düşünebileceğim birkaç yol var. Her ikisi de akış öğelerini depolar. Öğeleri saklamadan bir akışı tersine çevirmenin bir yolunu bilmiyorum.
Bu ilk yol, öğeleri bir dizide saklar ve ters sırada bir akışa okur. Akış öğelerinin çalışma zamanı türünü bilmediğimizden, diziyi düzgün bir şekilde yazamadığımızı ve denetlenmeyen bir döküm gerektirdiğini unutmayın.
@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]);
}
Başka bir teknik, öğeleri ters çevrilmiş bir listede toplamak için toplayıcıları kullanır. Bu, ArrayList
nesnelerin önünde çok sayıda ekleme yapar , bu nedenle çok sayıda kopyalama devam eder.
Stream<T> input = ... ;
List<T> output =
input.collect(ArrayList::new,
(list, e) -> list.add(0, e),
(list1, list2) -> list1.addAll(0, list2));
Muhtemelen bir çeşit özelleştirilmiş veri yapısı kullanarak çok daha verimli bir ters toplayıcı yazmak mümkündür.
GÜNCELLEME 2016-01-29
Bu soru son zamanlarda biraz ilgi gördüğü için, ön tarafa yerleştirme ile ilgili sorunu çözmek için cevabımı güncellemeliyim ArrayList
. Bu, O (N ^ 2) kopyalamayı gerektiren çok sayıda elemanla korkunç derecede verimsiz olacaktır.
ArrayDeque
Önde yerleştirmeyi etkili bir şekilde destekleyen bir bunun yerine kullanılması tercih edilir . Küçük bir kırışıklık şu üç arg biçimini kullanamayız Stream.collect()
; ikinci argümanın içeriğinin ilk argümanla birleştirilmesini gerektirir ve "önden ekle" toplu işlem yapılmaz Deque
. Bunun yerine, addAll()
birinci argümanın içeriğini ikincinin sonuna eklemek için kullanırız ve sonra ikinciyi döndürürüz. Bunun için Collector.of()
fabrika yönteminin kullanılması gerekir .
Kodun tamamı şudur:
Deque<String> output =
input.collect(Collector.of(
ArrayDeque::new,
(deq, t) -> deq.addFirst(t),
(d1, d2) -> { d2.addAll(d1); return d2; }));
Sonuç, a Deque
yerine kullanılır List
, ancak artık tersine çevrilmiş sırada kolayca yinelenebileceği veya yayınlanabileceği için bu çok fazla bir sorun olmamalıdır.
IntStream
yoktur.sorted(Comparator)
;Stream<Integer>
birIntStream