สำหรับคำถามที่เฉพาะเจาะจงในการสร้างสิ่งที่ตรงกันข้าม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)
ควรใช้ArrayDeque
แทนซึ่งสนับสนุนการแทรกที่ด้านหน้าได้อย่างมีประสิทธิภาพ รอยย่นขนาดเล็กคือเราไม่สามารถใช้รูปแบบสามหาเรื่องของStream.collect()
; มันต้องใช้เนื้อหาของหาเรื่องที่สองจะรวมเข้าหาเรื่องแรกและไม่มี "add-ทั้งหมดที่หน้า" Deque
การดำเนินการเป็นกลุ่มบน แต่เราใช้addAll()
เพื่อเพิ่มเนื้อหาของอาร์กิวเมนต์แรกไปยังจุดสิ้นสุดของวินาทีและจากนั้นเราจะส่งกลับสอง สิ่งนี้ต้องใช้Collector.of()
วิธีการจากโรงงาน
รหัสที่สมบูรณ์คือ:
Deque<String> output =
input.collect(Collector.of(
ArrayDeque::new,
(deq, t) -> deq.addFirst(t),
(d1, d2) -> { d2.addAll(d1); return d2; }));
ผลลัพธ์คือDeque
แทนที่จะเป็น a List
แต่ไม่น่าเป็นปัญหามากนักเนื่องจากสามารถวนซ้ำหรือสตรีมได้อย่างง่ายดายในลำดับที่กลับด้านตอนนี้
IntStream
ไม่มี.sorted(Comparator)
วิธี; คุณจะต้องไปผ่านStream<Integer>
ครั้งแรกและย้อนกลับก่อนที่จะมีผลผลิตIntStream