2017-12-14 87 views
6

Tôi không cảm thấy sự khác biệt giữa các phương pháp map()mapToObj() trong Java 8 luồng. Trong cả hai chúng ta có thể tạo và trả về các đối tượng cho các luồng, vậy tại sao các phương thức này tồn tại dưới dạng hai, không chỉ một.Sự khác biệt về luồng Java giữa bản đồ và bản đồToObj

Bạn có thể cho tôi giải thích bằng các ví dụ không?

+4

Chúng chỉ tồn tại trên các dòng nguyên thủy, trong đó 'bản đồ' hoạt động để ánh xạ loại nguyên thủy cho chính nó, ví dụ: 'IntStream.map (IntOperator)'. –

Trả lời

11

Bạn sẽ thấy mẫu tuyệt đẹp này. Các lớp học Stream bao gồm IntStream, LongStream, DoubleStream v.v. Điều này là để bạn có thể sử dụng các kiểu nguyên thủy trong các hoạt động của luồng. Bởi vì nếu không, bạn phải sử dụng Stream<Integer> hoặc Stream<Double>, sẽ đóng hộp các giá trị.

Tương tự, các phương pháp map cũng thực hiện việc này. Trong lớp học Stream<T>, có các phương pháp mapToInt, mapToDouble nhưng tình huống có một chút khác biệt trong các lớp học IntStream, DoubleStream.

Trong IntStream, phương pháp map mất IntUnaryOperator, ánh xạ một int vào int. Nếu bạn muốn ánh xạ luồng tới số Stream<T>, bạn phải sử dụng mapToObj. mapToObj là tên tốt vì nó phân biệt với map ánh xạ tới int. Nó biểu thị rằng luồng thay đổi từ IntStream thành số Stream<T>. Lý do tại sao mapToObj được đặt tên như vậy là lý do tương tự tại sao mapToInt được đặt tên như vậy - để biểu thị một sự thay đổi trong các loại Stream/

+2

Bạn có thể thêm đề cập đến phương thức 'đóng hộp()' chuyển giữa ví dụ 'IntStream' và' Stream 'và phù hợp với mẫu này. – daniu

3

các primitiveobject phiên bản của các kiểu dữ liệu (ví dụ int và Integer, double và Double, vv) không thực sự tương thích với nhau trong Java. Chúng được làm tương thích thông qua bước bổ sung của auto-boxing/unboxing. Vì vậy, nếu bạn có một dòng ints nguyên thủy và nếu bạn cố gắng sử dụng các phiên bản đối tượng của dòng và chức năng (tức là dòng và chức năng, bạn sẽ phải chịu chi phí đấm bốc và unboxing các chi phí của boxing và unboxing các yếu tố. gói chức năng chứa primitive specialized versions of streams cũng như functional interfaces. Ví dụ, thay vì sử dụng Stream<Integer>, bạn nên sử dụng IntStream. Bây giờ bạn có thể xử lý từng phần tử của dòng sử dụng IntFunction. Điều này sẽ tránh auto-boxing/unboxing hoàn toàn.

vì vậy , bất cứ khi nào bạn muốn xử lý các luồng nguyên tố nguyên thủy, bạn nên sử dụng các luồng chuyên biệt nguyên thủy (tức là IntStream, LongStream và DoubleStream) và inte chức năng chuyên biệt nguyên thủy rfaces (tức là IntFunction, IntConsumer, IntSupplier vv) để đạt được hiệu suất tốt hơn.

Một điều nữa cần lưu ý là không có giao diện chức năng đặc biệt nguyên thủy (chẳng hạn như IntFunction, DoubleFunction hoặc IntConsumer) mở rộng giao diện chức năng không nguyên thủy (tức là Chức năng, Người tiêu dùng, v.v.).

java.util.function package chứa các phiên bản int, double và long (nhưng không có float) của tất cả các giao diện chức năng. Ví dụ, có một IntFunction, một DoubleFunction, và một LongFunction, đó là int, double, và dài, các phiên bản của Function. Các chức năng này được sử dụng cùng với các phiên bản chuyên biệt nguyên thủy của các luồng như IntStream, DoubleStream và LongStream.

Chúng ta hãy một số ví dụ:

Stream stream = Stream.of(1, 2, 3); //Will compile fine 
IntStream intStream = IntStream.of(4, 5, 6); //Will compile fine 

Stream s = IntStream.of(4, 5, 6); //Does not compile 
Stream s = IntStream.of(4, 5, 6).mapToObj(e -> e); //mapToObj method is needed 
IntStream is = Stream.of(4, 5, 6).mapToInt(e -> e); //mapToInt method is needed 

Như một kết luận, lý do bạn có thể sử dụng mapToObj cũng giống như bạn có thể sử dụng mapToInt, mà là để thay đổi kiểu Stream.

Các vấn đề liên quan