Tại sao char [] là mảng duy nhất không được Arrays.stream () hỗ trợ?


43

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?


3
stackoverflow.com/questions/22435333/ Từ Chủ đề này IMO giải quyết một câu hỏi liên quan
Mark Bramnik

Câu trả lời:


31

Như Eran đã nói, đó không phải là người duy nhất mất tích.

A BooleanStreamsẽ là vô dụng, một ByteStream(nếu nó tồn tại) có thể được xử lý như một InputStreamhoặc chuyển đổi thành IntStream(như có thể short), và floatcó thể được xử lý như một DoubleStream.

Vì dù sao charcũ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 BooleanStreamsẽ 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?


7
"A BooleanStreamsẽ là vô dụng": tại sao?
glglgl

12
Có thực sự không hợp lý khi cho rằng ai đó có thể cần phải làm, ví dụ reduce(Boolean::logicalAnd), hoặc reduce(Boolean::logicalOr)trên boolean[]? Sau khi tất cả, các phương pháp logicalAndlogicalOrđã đượ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.
Holger

2
@Holger chỉ vì Boolean::logicalAndtồ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 đó.
Kayaman

4
Tôi không thấy những gì bạn đang cố gắng đưa ra. Ở dạng cực đoan: "Tôi có thể tưởng tượng rằng ai đó sẽ muốn làm 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]"
Alexander - Tái lập lại

11
Đối với tôi, dường như lý do duy nhất không có <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>
Alexander - Tái lập lại

32

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.

Nguồn

Ô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).

Nguồn

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

2
Ai đó có thể làm rõ những gì họ có nghĩa là 100K+ of JDK footprint?
yassin

3
@yassin Có người phải viết mã. Ông đang ước tính rằng mỗi chuyên môn hóa của luồng là hơn 100.000 dòng mã
Michael

3
@BulgarSadykov Những câu hỏi như vậy về " tại sao X giống Y " thường bị đóng dưới dạng dựa trên quan điểm vì không thể đọc được suy nghĩ của tác giả ban đầu và, trừ khi chúng tình cờ xuất hiện, tất cả những gì bạn sẽ nhận được là phỏng đoán. Nếu tôi hỏi "làm cách nào để gửi yêu cầu POST với máy khách HTTP của Apache?", Bất kỳ ai quen thuộc với thư viện đều có thể trả lời câu hỏi đó. Tại sao một thư viện được thiết kế theo cách thường không thể trả lời. Lý do duy nhất chúng tôi có thể trả lời điều này thực sự là vì có một hồ sơ công khai về các cuộc trò chuyện của họ. Đó là những gì tôi đã cố gắng để có được với câu đầu tiên.
Michael

2
@BulgarSadykov cũng nhắc về điều này, đề cập đến blog của Eric Lippert, về C #, nhưng về chủ đề "tại sao tính năng Foo không được triển khai bằng ngôn ngữ" stackoverflow.com/a/5588850/479251
Pac0

2
@BulgarSadykov Tôn trọng không đồng ý. Một lần nữa, tôi nhắc lại câu hỏi ví dụ của mình về " làm cách nào để gửi yêu cầu POST với máy khách HTTP của Apache? ". Một câu trả lời cho câu hỏi đó rõ ràng không bắt đầu bằng " bởi vì đó là những gì các nhà thiết kế quyết định ". Tôi không thay đổi từ ngữ, xin lỗi.
Michael

7

Đó không chỉ là charmảng không được hỗ trợ.

Chỉ có 3 loại suối nguyên thủy - IntStream, LongStreamDoubleStream .

Kết quả là, Arrayscó phương pháp chuyển đổi int[], long[]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[]float[], vì các loại nguyên thủy đã không tương ứng với dòng nguyên thủy.


4
"Vì các loại nguyên thủy này không có luồng nguyên thủy tương ứng." Sau đó, câu hỏi tiếp theo sẽ là "tại sao"?
Federico klez Culloca

7
@FedericoklezCulloca câu hỏi tiếp theo được trả lời ở đây
Eran

6

charlà 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 charcó 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 charvà có thể sử dụng java.text.Normalizercho một dạng điểm mã / chuỗi Unicode chính tắc duy nhất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.