Trong khi thực hiện các cách chuyển đổi mảng nguyên thủy thành Luồng, tôi thấy rằng char[]
không được hỗ trợ trong khi các loại mảng nguyên thủy khác được hỗ trợ. Bất kỳ lý do cụ thể để bỏ chúng trong dòng?
Trong khi thực hiện các cách chuyển đổi mảng nguyên thủy thành Luồng, tôi thấy rằng char[]
không được hỗ trợ trong khi các loại mảng nguyên thủy khác được hỗ trợ. Bất kỳ lý do cụ thể để bỏ chúng trong dòng?
Câu trả lời:
Như Eran đã nói, đó không phải là người duy nhất mất tích.
A BooleanStream
sẽ là vô dụng, một ByteStream
(nếu nó tồn tại) có thể được xử lý như một InputStream
hoặc chuyển đổi thành IntStream
(như có thể short
), và float
có thể được xử lý như một DoubleStream
.
Vì dù sao char
cũng không thể đại diện cho tất cả các ký tự (xem được liên kết), nó sẽ là một chút của một dòng di sản. Mặc dù hầu hết mọi người không phải đối phó với tiền mã hóa nào, vì vậy nó có vẻ lạ. Tôi có nghĩa là bạn sử dụng String.charAt()
mà không nghĩ rằng "điều này không thực sự hoạt động trong mọi trường hợp".
Vì vậy, một số thứ đã bị bỏ đi vì chúng không được coi là quan trọng. Như đã nói của JB Nizet trong câu hỏi được liên kết :
Các nhà thiết kế rõ ràng đã chọn để tránh sự bùng nổ của các lớp và phương thức bằng cách giới hạn các luồng nguyên thủy thành 3 loại, vì các loại khác (char, short, float) có thể được biểu diễn bằng tương đương lớn hơn (int, double) mà không bị phạt hiệu năng đáng kể.
Lý do BooleanStream
sẽ là vô ích, bởi vì bạn chỉ có 2 giá trị và điều đó giới hạn các hoạt động rất nhiều. Không có hoạt động toán học nào để làm, và bạn có thường xuyên làm việc với nhiều giá trị boolean không?
BooleanStream
sẽ là vô dụng": tại sao?
reduce(Boolean::logicalAnd)
, hoặc reduce(Boolean::logicalOr)
trên boolean[]
? Sau khi tất cả, các phương pháp logicalAnd
và logicalOr
đã được thêm vào trong Java 8, vì vậy tôi có thể làm những hoạt động giảm một Stream<Boolean>
... Bằng cách này, bạn có thể truyền qua char[]
dễ dàng như việc CharBuffer.wrap(array).chars()
hoặc CharBuffer.wrap(array).codePoints()
tuỳ mà ngữ nghĩa mà bạn thích.
Boolean::logicalAnd
tồn tại, nó không nhất thiết phải đảm bảo sự tồn tại của a BooleanStream
. Chúng có thể được sử dụng trong các tình huống lambda không phát trực tuyến. Tôi có thể tưởng tượng rằng ai đó sẽ muốn làm reduce(Boolean::logicalAnd)
, nhưng trong mọi trường hợp không ai cần phải làm điều đó.
while (i < limit)
, nhưng trong mọi trường hợp, không ai cần phải làm điều đó [bằng cách sử dụng các hướng dẫn lắp ráp nhánh và nhảy]"
<Primitive>Stream
đối với mọi loại nguyên thủy là vì nó sẽ làm hỏng API quá nhiều. Câu hỏi chính xác được đặt ra là "tại sao lại có IntStream
?" và câu trả lời đáng tiếc là bởi vì hệ thống loại của Java không đủ để thể hiện Stream<int>
mà không cần tất cả chi phí hiệu năng sử dụng Integer
. Nếu Java có các loại giá trị, có thể được phân bổ trên ngăn xếp hoặc nhúng trực tiếp vào các cấu trúc dữ liệu khác, thì sẽ không có nhu cầu nào như vậy ngoàiStream<T>
Tất nhiên, câu trả lời là " bởi vì đó là những gì các nhà thiết kế quyết định ". Không có lý do kỹ thuật tại saoCharStream
không thể tồn tại.
Nếu bạn muốn biện minh, bạn thường cần phải chuyển danh sách gửi thư OpenJDK *. Tài liệu của JDK không theo thói quen biện minh tại sao mọi thứ lại là lý do.
Có người hỏi
Sử dụng IntStream để biểu diễn luồng char / byte hơi bất tiện. Chúng ta có nên thêm CharStream và ByteStream không?
Câu trả lời từ Brian Goetz (Kiến trúc sư ngôn ngữ Java) cho biết
Câu trả lời ngắn gọn: không.
Nó không đáng giá hơn 100K + dấu chân JDK cho mỗi biểu mẫu được sử dụng gần như không bao giờ. Và nếu chúng ta thêm chúng, ai đó sẽ yêu cầu ngắn, nổi hoặc boolean.
Nói cách khác, nếu mọi người khăng khăng chúng tôi có tất cả các chuyên ngành nguyên thủy, chúng tôi sẽ không có chuyên môn nguyên thủy. Mà sẽ tồi tệ hơn hiện trạng.
Ông cũng nói tương tự ở nơi khác
Nếu bạn muốn đối phó với chúng như những ký tự, bạn có thể hạ thấp chúng xuống một cách dễ dàng. Có vẻ như không phải là một trường hợp sử dụng đủ quan trọng để có một tập hợp toàn bộ các luồng. (Tương tự với Short, Byte, Float).
TL; DR: Không xứng đáng với chi phí bảo trì.
* Trong trường hợp bạn tò mò, truy vấn google tôi đã sử dụng là
site:http://mail.openjdk.java.net/ charstream
100K+ of JDK footprint
?
Đó không chỉ là char
mảng không được hỗ trợ.
Chỉ có 3 loại suối nguyên thủy - IntStream
, LongStream
vàDoubleStream
.
Kết quả là, Arrays
có phương pháp chuyển đổi int[]
, long[]
vàdouble[]
để các con suối nguyên thủy tương ứng.
Không có phương pháp tương ứng cho boolean[]
, byte[]
, short[]
, char[]
và float[]
, vì các loại nguyên thủy đã không tương ứng với dòng nguyên thủy.
char
là một phần phụ thuộc của String
- lưu trữ các giá trị UTF-16. Biểu tượng Unicode, điểm mã , đôi khi là một cặp ký tự thay thế. Vì vậy, bất kỳ giải pháp đơn giản nào với ký tự chỉ bao gồm một phần của miền Unicode.
Có một thời gian char
có quyền riêng của mình là một loại công khai. Nhưng ngày nay tốt hơn là sử dụng điểm mã , một IntStream
. Một luồng char không thể xử lý đơn giản các cặp thay thế.
Một lý do phổ biến khác là mô hình "bộ xử lý" JVM sử dụng một int
"thanh ghi" nhỏ nhất, giữ các booleans, byte, quần short và cả ký tự trong một vị trí lưu trữ có kích thước int như vậy. Để không nhất thiết phải phình to các lớp java, người ta đã kiềm chế tất cả các biến thể sao chép có thể.
Trong tương lai xa, người ta có thể mong đợi các kiểu nguyên thủy được phép hoạt động như các tham số loại chung, cung cấp a List<int>
. Sau đó chúng ta có thể thấy a Stream<char>
.
Hiện tại, tốt hơn nên tránh char
và có thể sử dụng java.text.Normalizer
cho một dạng điểm mã / chuỗi Unicode chính tắc duy nhất.