2016-05-16 19 views
6

Trong câu hỏi this nó đã được trả lời rằng cả hai biểu thức đều bằng nhau, nhưng trong trường hợp này chúng tạo ra các kết quả khác nhau. Đối với một int[] scores nhất định, tại sao công việc này:Arrays.stream (mảng) vs Arrays.asList (mảng) .stream()

Arrays.stream(scores) 
     .forEach(System.out::println); 

... nhưng điều này không:

Arrays.asList(scores).stream() 
     .forEach(System.out::println); 

Theo như tôi biết .stream() có thể được gọi vào bất kỳ Collection, mà Lists chắc chắn đang có. Đoạn mã thứ hai chỉ trả về một luồng chứa toàn bộ mảng thay vì các phần tử.

Trả lời

13

Hành vi bạn thấy không cụ thể đối với Stream s. Arrays.asList(scores) trả về số List<int[]> khi bạn chuyển đến số int[], vì thông số loại chung không thể được thay thế bằng loại nguyên thủy. Do đó, khi bạn gọi asList(T... a), trình biên dịch sử dụng int[] thay cho số T.

Nếu bạn thay đổi scores thành Integer[], bạn sẽ nhận được kết quả mong đợi (ví dụ: Arrays.asList(scores) sẽ trả lại List<Integer>).

+0

tôi nhìn thấy. Nó chỉ là lạ bởi vì tôi nhớ tôi làm công cụ như vậy trong quá khứ và nó đã làm việc. Nó có hoạt động không nếu tôi đã tuyên bố trước Danh sách như thế này: 'Danh sách scoreAsList = new ArrayList <> (điểm); '? – AdHominem

+3

@AdHominem Điều đó sẽ không hoạt động, vì bạn không thể chuyển mảng vào một hàm tạo 'ArrayList'. Bạn chỉ có thể vượt qua một Bộ sưu tập. – Eran

+0

Như một lưu ý phụ, 'Stream.of (điểm) .forEach (System.out :: println);' cũng giống như 'Arrays.asList (điểm) .stream(). ForEach (Hệ thống.out :: println); '… – Holger

7

Lý do đoạn mã thứ hai không hoạt động là không có điều nào như List<int> trong Java. Đó là lý do tại sao Arrays.asList(scores) không tạo ra những gì bạn mong đợi.

Chuyển từ int[] sang Integer[] sẽ khắc phục vấn đề này, theo nghĩa là hai đoạn mã sẽ tạo ra kết quả giống hệt nhau. Tuy nhiên, mã của bạn sẽ kém hiệu quả hơn, bởi vì tất cả int s sẽ được đóng hộp.

Thực tế, hiệu quả là lý do đằng sau sự quá tải của stream đối với mảng nguyên thủy. Cuộc gọi của bạn Arrays.stream(scores) được chuyển đến stream(int[] array), sản xuất đối tượng IntStream. Bây giờ bạn có thể áp dụng .forEach(System.out::println), gọi println(int), một lần nữa tránh đấm bốc.

+1

Xin cầu nguyện cho dự án Valhalla sau đó: D –

+0

@ java8.being: kể từ khi viết một trình bao bọc' Danh sách' cho một 'int []' là khoảng mười dòng mã, và cho dòng, 'Mảng. stream (score) 'đã hoạt động, tôi không thấy điểm cầu nguyện cho một cái gì đó mà chúng ta thậm chí không biết nó sẽ thay đổi như thế nào về vấn đề này ... – Holger

+0

@ Holger Tôi muốn nói về dòng này: 'Lý do đoạn mã thứ hai không hoạt động là không có thứ gì trong Danh sách trong Java.' –

0

Mảng.asList dự kiến ​​mảng của đối tượng không phải mảng của nguyên thủy. Nó không phàn nàn về thời gian biên dịch vì mảng nguyên thủy là một đối tượng.

Có thể lấy một đối tượng làm danh sách nhưng bên trong đối tượng (mảng nguyên thủy là đối tượng) không thể chuyển đổi thành danh sách.

Mảng của nguyên thủy có thể được chuyển đổi sang dòng sử dụng IntStream, DoubleStreamLongStream

như thế này

double[] doubleArray = {1.1,1.2,1.3}; 

DoubleStream.of(doubleArray).forEach(System.out::println); 


int[] intArray = {1,2,3,4,5,6}; 

IntStream.of(intArray).forEach(System.out::println); 


long[] longArray = {1L,2L,3L}; 

LongStream.of(longArray).forEach(System.out::println); 
+0

Có gì sai với câu trả lời của tôi? Ít nhất bạn nên bình luận. –

+0

Nó chắc chắn giúp, làm thế nào int [] điểm có thể được chuyển đổi để dòng. –

+0

tốt hơn nhiều bây giờ +1 – Hulk