ในขณะที่ทำตามวิธีการแปลงอาร์เรย์ดั้งเดิมเป็นสตรีมฉันพบchar[]ว่าไม่ได้รับการสนับสนุนในขณะที่สนับสนุนประเภทอาร์เรย์ดั้งเดิมอื่น ๆ มีเหตุผลใดที่ทำให้พวกเขาออกจากกระแส?
ในขณะที่ทำตามวิธีการแปลงอาร์เรย์ดั้งเดิมเป็นสตรีมฉันพบchar[]ว่าไม่ได้รับการสนับสนุนในขณะที่สนับสนุนประเภทอาร์เรย์ดั้งเดิมอื่น ๆ มีเหตุผลใดที่ทำให้พวกเขาออกจากกระแส?
คำตอบ:
อย่างที่ Eran กล่าวมันไม่ใช่สิ่งเดียวที่ขาดหายไป
BooleanStreamจะไร้ประโยชน์เป็นByteStream(ถ้ามันมีตัวตน) สามารถจัดการได้เป็นInputStreamหรือแปลงIntStream(เป็นได้short) และสามารถจัดการได้เป็นfloatDoubleStream
เนื่องจาก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, และLongStreamDoubleStream
เป็นผลให้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 ในรูปแบบที่เป็นเอกลักษณ์