ในขณะที่ทำตามวิธีการแปลงอาร์เรย์ดั้งเดิมเป็นสตรีมฉันพบchar[]
ว่าไม่ได้รับการสนับสนุนในขณะที่สนับสนุนประเภทอาร์เรย์ดั้งเดิมอื่น ๆ มีเหตุผลใดที่ทำให้พวกเขาออกจากกระแส?
ในขณะที่ทำตามวิธีการแปลงอาร์เรย์ดั้งเดิมเป็นสตรีมฉันพบchar[]
ว่าไม่ได้รับการสนับสนุนในขณะที่สนับสนุนประเภทอาร์เรย์ดั้งเดิมอื่น ๆ มีเหตุผลใดที่ทำให้พวกเขาออกจากกระแส?
คำตอบ:
อย่างที่ Eran กล่าวมันไม่ใช่สิ่งเดียวที่ขาดหายไป
BooleanStream
จะไร้ประโยชน์เป็นByteStream
(ถ้ามันมีตัวตน) สามารถจัดการได้เป็นInputStream
หรือแปลงIntStream
(เป็นได้short
) และสามารถจัดการได้เป็นfloat
DoubleStream
เนื่องจากchar
ไม่สามารถแสดงอักขระทั้งหมดได้ (ดูที่เชื่อมโยง) จึงเป็นบิตของการรับชมแบบดั้งเดิม แม้ว่าคนส่วนใหญ่ไม่จำเป็นต้องจัดการกับ codepoints ต่อไปดังนั้นมันอาจดูแปลก ฉันหมายถึงคุณใช้String.charAt()
โดยไม่ต้องคิดว่า "มันใช้ไม่ได้กับทุกกรณี"
ดังนั้นจึงมีบางสิ่งเหลืออยู่เพราะพวกเขาไม่ถือว่าสำคัญ ตามที่กล่าวโดย JB Nizet ในคำถามที่เชื่อมโยง :
นักออกแบบเลือกที่จะหลีกเลี่ยงการระเบิดของคลาสและวิธีการอย่างชัดเจนโดย จำกัด การสตรีมแบบดั้งเดิมเป็น 3 ประเภทเนื่องจากประเภทอื่น (char, short, float) สามารถถูกแทนด้วยขนาดที่ใหญ่กว่า (int, double) โดยไม่มีการลงโทษประสิทธิภาพที่สำคัญ
เหตุผลBooleanStream
จะไร้ประโยชน์เนื่องจากคุณมีเพียง 2 ค่าและ จำกัด การดำเนินการเป็นจำนวนมาก ไม่มีการดำเนินการทางคณิตศาสตร์ที่ต้องทำและคุณทำงานกับค่าบูลีนบ่อยแค่ไหน?
BooleanStream
จะไร้ประโยชน์": ทำไม
reduce(Boolean::logicalAnd)
หรือreduce(Boolean::logicalOr)
บน a boolean[]
? ท้ายที่สุดแล้ววิธีการlogicalAnd
และlogicalOr
ได้รับการเพิ่มใน Java 8 ดังนั้นฉันสามารถดำเนินการลดลงของStream<Boolean>
... โดยวิธีการที่คุณสามารถสตรีมมากกว่าchar[]
ง่ายCharBuffer.wrap(array).chars()
หรือCharBuffer.wrap(array).codePoints()
ขึ้นอยู่กับความหมายที่คุณต้องการ
Boolean::logicalAnd
BooleanStream
สิ่งเหล่านี้สามารถใช้ในสถานการณ์แลมบ์ดาแบบไม่สตรีมได้ ฉันสามารถจินตนาการได้ว่ามีใครบางคนต้องการที่จะทำreduce(Boolean::logicalAnd)
แต่ไม่มีใครที่จะต้องทำ
while (i < limit)
แต่ไม่ว่าในกรณีใด ๆ ก็ไม่มีใครจำเป็นต้องทำ [ใช้คำสั่งการชุมนุมสาขาและกระโดดข้าม]"
<Primitive>Stream
สำหรับทุกประเภทดั้งเดิมคือเพราะมันจะขยาย API มากเกินไป คำถามที่ถูกต้องที่จะถามคือ "ทำไมถึงมีIntStream
ทั้งหมด?" และคำตอบที่โชคร้ายก็คือเนื่องจากระบบประเภทของ Java นั้นไม่ได้มีความสมบูรณ์เพียงพอที่จะแสดงออกStream<int>
โดยไม่ต้องเสียค่าใช้จ่ายด้านประสิทธิภาพในการใช้งานInteger
ทั้งหมด หาก Java มีชนิดของค่าซึ่งสามารถจัดสรรให้กับสแต็กหรือฝังแบบอินไลน์โดยตรงภายในโครงสร้างข้อมูลอื่น ๆ ก็ไม่จำเป็นต้องมีสิ่งใดนอกจากStream<T>
แน่นอนคำตอบคือ " เพราะนั่นคือสิ่งที่นักออกแบบตัดสินใจ " ไม่มีเหตุผลทางเทคนิคว่าทำไมCharStream
ไม่มีตัวตน
หากคุณต้องการเหตุผลคุณจะต้องเปลี่ยนรายชื่อผู้รับจดหมาย OpenJDK * เอกสารของ JDK ไม่ได้อยู่ในลักษณะที่ว่าเหตุผลว่าทำไมอะไรถึงเป็นเหตุผล
มีคนถาม
การใช้ IntStream เพื่อแทน char / byte stream นั้นไม่สะดวกนัก เราควรเพิ่ม CharStream และ ByteStream ด้วยหรือไม่
คำตอบจาก Brian Goetz (สถาปนิกภาษา Java) กล่าวว่า
คำตอบสั้น ๆ : ไม่
มันไม่คุ้มค่าอีก 100K + ของรอยเท้า JDK สำหรับแบบฟอร์มเหล่านี้ซึ่งแทบไม่เคยใช้เลย และถ้าเราเพิ่มสิ่งเหล่านี้บางคนก็ต้องการความสั้นลอยหรือบูลีน
อีกวิธีหนึ่งถ้าคนยืนยันว่าเรามีความเชี่ยวชาญดั้งเดิมทั้งหมดเราจะไม่มีความเชี่ยวชาญดั้งเดิม ซึ่งจะแย่กว่าสถานะเดิม
เขายังพูดเหมือนกันที่อื่น
หากคุณต้องการจัดการกับพวกเขาเป็นตัวอักษรคุณสามารถ downcast พวกเขาเพื่อตัวอักษรได้ง่ายพอ ดูเหมือนจะไม่ได้เป็นกรณีการใช้งานที่สำคัญพอที่จะมีสตรีมชุดหนึ่งทั้งหมด (เหมือนกับ Short, Byte, Float)
TL; DR: ไม่คุ้มกับค่าบำรุงรักษา
* ในกรณีที่คุณอยากรู้คำค้นหา google ที่ฉันใช้คือ
site:http://mail.openjdk.java.net/ charstream
100K+ of JDK footprint
?
ไม่ใช่เฉพาะchar
อาร์เรย์ที่ไม่รองรับ
มีเพียง 3 ประเภทของลำธารดั้งเดิมมี - IntStream
, และLongStream
DoubleStream
เป็นผลให้Arrays
มีวิธีการที่แปลงint[]
, long[]
และdouble[]
ไปที่ลำธารดั้งเดิมที่สอดคล้องกัน
ไม่มีวิธีการที่สอดคล้องกันสำหรับการมีboolean[]
, byte[]
, short[]
, char[]
และfloat[]
ตั้งแต่เหล่านี้ชนิดดั้งเดิมไม่มีสอดคล้องลำธารดั้งเดิม
char
เป็นส่วนหนึ่งของString
- การจัดเก็บค่า UTF-16 สัญลักษณ์ยูนิโค้ดซึ่งเป็นจุดรหัสบางครั้งก็เป็นตัวอักษรคู่แทน ดังนั้นวิธีง่ายๆที่มีตัวอักษรครอบคลุมเฉพาะส่วนหนึ่งของโดเมน Unicode
มีเวลาที่char
มีสิทธิ์เป็นแบบสาธารณะ แต่ปัจจุบันมันจะดีกว่าที่จะใช้จุดรหัสIntStream
การ สตรีมของถ่านไม่สามารถจัดการกับคู่ตัวแทนได้อย่างตรงไปตรงมา
อีกเหตุผลที่น่าเป็นห่วงมากกว่าคือโมเดล "JVM" โปรเซสเซอร์ "ใช้int
" register "ที่เล็กที่สุดโดยเก็บบูลีนไบต์ไบต์กางเกงขาสั้นและตัวอักษรในที่เก็บข้อมูลขนาดใหญ่ ในการที่ไม่จำเป็นต้องมีคลาสของ bloat java เราจะละเว้นการคัดลอกหนึ่งชุดที่เป็นไปได้
ในอนาคตไกลList<int>
หนึ่งอาจคาดหวังชนิดดั้งเดิมได้รับอนุญาตให้ฟังก์ชั่นเป็นพารามิเตอร์ประเภททั่วไปให้ Stream<char>
จากนั้นเราอาจจะเห็น
สำหรับช่วงเวลาที่ดีควรหลีกเลี่ยงchar
และอาจใช้java.text.Normalizer
สำหรับรหัสจุด / สตริง Unicode ในรูปแบบที่เป็นเอกลักษณ์