ฉันทำการสอบสวนในรายชื่อผู้รับจดหมายแลมด้าหลายโครงการและฉันคิดว่าฉันพบการสนทนาที่น่าสนใจสองสามข้อ
ฉันไม่พบคำอธิบายที่น่าพอใจ หลังจากอ่านทั้งหมดฉันสรุปได้ว่ามันเป็นแค่การละเว้น แต่คุณจะเห็นได้ว่ามีการพูดคุยกันหลายครั้งในช่วงหลายปีที่ผ่านมาระหว่างการออกแบบ API
ผู้เชี่ยวชาญด้านข้อมูลจำเพาะของแลมบ์ดา Libs
ฉันพบการสนทนาเกี่ยวกับเรื่องนี้ในรายการส่งเมลผู้เชี่ยวชาญของ Lambda Libs :
ภายใต้Iterable / Iterator.stream () Sam Pullara กล่าวว่า:
ฉันทำงานกับ Brian เพื่อดูว่าขีด จำกัด / ฟังก์ชันการทำงานย่อย [1] อาจถูกนำไปใช้และเขาแนะนำให้เปลี่ยนเป็น Iterator เป็นวิธีที่เหมาะสมในการดำเนินการ ฉันคิดเกี่ยวกับวิธีแก้ปัญหานั้น แต่ไม่พบวิธีที่ชัดเจนในการใช้ตัววนซ้ำและเปลี่ยนเป็นกระแส ปรากฎว่ามันอยู่ในนั้นคุณเพียงแค่ต้องแปลง iterator เป็น spliterator ก่อนจากนั้นแปลง spliterator เป็น stream ดังนั้นสิ่งนี้ทำให้ฉันทบทวนว่าเราควรจะแขวนสิ่งเหล่านี้จาก Iterable / Iterator โดยตรงหรือทั้งสองอย่าง
คำแนะนำของฉันคืออย่างน้อยก็มีไว้ใน Iterator เพื่อให้คุณสามารถเคลื่อนย้ายระหว่างโลกทั้งสองได้อย่างหมดจดและจะสามารถค้นพบได้ง่ายแทนที่จะต้องทำ:
Streams.stream (Spliterators.spliteratorUnknownSize (iterator, Spliterator.ORDERED))
แล้วBrian Goetz ตอบกลับ :
ฉันคิดว่าประเด็นของแซมคือมีห้องสมุดมากมายที่ให้ Iterator แก่คุณ แต่อย่าปล่อยให้คุณเขียน spliterator ของคุณเอง ดังนั้นสิ่งที่คุณสามารถทำได้คือการโทรกระแส (spliteratorUnknownSize (iterator)) แซมแนะนำให้เรากำหนด Iterator.stream () ให้ทำเพื่อคุณ
ฉันต้องการเก็บเมธอดสตรีม () และ spliterator () ไว้สำหรับผู้เขียนห้องสมุด / ผู้ใช้ขั้นสูง
และหลังจากนั้น
"เนื่องจากการเขียน Spliterator นั้นง่ายกว่าการเขียน Iterator ฉันต้องการเขียน Spliterator แทนที่จะเป็น Iterator (Iterator นั้น 90s :)
แม้ว่าคุณจะพลาดจุดนี้ มี zillions ของการเรียนออกมีที่มีอยู่แล้วในมือคุณ Iterator และหลายคนยังไม่พร้อมจำหน่าย
การสนทนาก่อนหน้าในรายชื่อผู้รับจดหมายแลมบ์ดา
นี่อาจไม่ใช่คำตอบที่คุณกำลังมองหา แต่ในรายชื่อผู้รับจดหมายของโครงการแลมบ์ดานี้มีการพูดคุยสั้น ๆ บางทีนี่อาจช่วยส่งเสริมการอภิปรายที่กว้างขึ้นในเรื่อง
ในคำพูดของ Brian Goetz ภายใต้Streams จาก Iterable :
ก้าวถอยหลัง ...
มีหลายวิธีในการสร้างสตรีม ยิ่งคุณมีข้อมูลเกี่ยวกับวิธีการอธิบายองค์ประกอบมากเท่าไหร่ฟังก์ชันการทำงานและประสิทธิภาพที่ห้องสมุดลำธารจะมอบให้คุณก็จะมากขึ้นเท่านั้น เพื่อให้ข้อมูลน้อยที่สุดพวกเขาคือ:
iterator
ขนาดตัววนซ้ำ +
Spliterator
Spliterator ที่รู้ขนาดของมัน
Spliterator ที่รู้ขนาดของมันและรู้เพิ่มเติมว่าการแบ่งย่อยทั้งหมดรู้ขนาดของมัน
(บางคนอาจประหลาดใจที่พบว่าเราสามารถแยกคู่ขนานได้จากตัววนซ้ำในกรณีที่ Q (ทำงานต่อองค์ประกอบ) เป็นสิ่งที่ไม่สำคัญ)
หาก Iterable มีเมธอดสตรีม () ก็จะหุ้ม Iterator ด้วย Spliterator โดยไม่มีข้อมูลขนาด แต่สิ่งที่ Iterable ส่วนใหญ่มีข้อมูลขนาด ซึ่งหมายความว่าเราให้บริการสตรีมที่ไม่เพียงพอ นั่นไม่ดีเลย
ข้อเสียข้อหนึ่งของการฝึกฝน API ที่ร่างโดย Stephen ที่นี่เพื่อยอมรับ Iterable แทนที่จะเป็น Collection คือคุณกำลังบังคับให้สิ่งต่าง ๆ ผ่าน "ท่อเล็ก ๆ " และทิ้งข้อมูลขนาดเมื่อมันอาจมีประโยชน์ ไม่เป็นไรถ้าทุกสิ่งที่คุณต้องทำมีไว้สำหรับทุกคน แต่ถ้าคุณต้องการทำมากกว่านี้มันจะดีกว่าถ้าคุณสามารถเก็บรักษาข้อมูลทั้งหมดที่คุณต้องการ
ค่าเริ่มต้นที่จัดทำโดย Iterable จะเป็นเส็งเคร็งแน่นอน - มันจะยกเลิกขนาดแม้ว่า Iterables ส่วนใหญ่จะรู้ข้อมูลนั้น
ความขัดแย้ง?
ถึงแม้ว่าดูเหมือนว่าการสนทนาจะขึ้นอยู่กับการเปลี่ยนแปลงที่กลุ่มผู้เชี่ยวชาญทำกับการออกแบบเริ่มต้นของสตรีมซึ่งเริ่มต้นจากการทำซ้ำ
ถึงกระนั้นก็เป็นที่น่าสนใจที่จะสังเกตเห็นว่าในอินเตอร์เฟซเช่นคอลเลกชัน, วิธีการสตรีมถูกกำหนดเป็น:
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
ซึ่งอาจเป็นรหัสเดียวกันที่ถูกใช้ในส่วนต่อประสาน Iterable
ดังนั้นนี่คือเหตุผลที่ฉันพูดว่าคำตอบนี้อาจไม่เป็นที่น่าพอใจ แต่ก็ยังน่าสนใจสำหรับการอภิปราย
หลักฐานการเปลี่ยนสถานะ
ดำเนินการต่อกับการวิเคราะห์ในรายชื่อผู้รับจดหมายดูเหมือนว่าวิธี splitIterator เดิมในอินเตอร์เฟซการเก็บรวบรวมและในบางจุดในปี 2013 พวกเขาย้ายมันขึ้นเพื่อ Iterable
ดึง splitIterator เพิ่มขึ้นจากการเก็บเพื่อ Iterable
สรุป / ทฤษฎี?
โอกาสที่ว่าการขาดวิธีใน Iterable เป็นเพียงการละเว้นเนื่องจากดูเหมือนว่าพวกเขาควรจะย้ายวิธีการสตรีมด้วยเช่นกันเมื่อพวกเขาย้ายตัวแยกสัญญาณขึ้นจากคอลเลกชันไปยัง Iterable
หากมีเหตุผลอื่นที่ไม่ชัดเจน มีใครอีกบ้างที่มีทฤษฎีอื่น ๆ