Làm thế nào để chuyển đổi một dòng Java 8 thành một mảng?


459

Cách dễ nhất/ngắn nhất để chuyển đổi Java 8 Stream thành một mảng là gì?

+2

Tôi khuyên bạn nên hoàn nguyên quá trình quay lại vì câu hỏi đã hoàn chỉnh hơn và cho thấy bạn đã thử một cái gì đó. 15 apr. 142014-04-15 09:13:21

  0

@skiwi Cảm ơn! nhưng tôi nghĩ rằng mã cố gắng không thực sự thêm thông tin cho câu hỏi, và không ai đã hét lên "cho chúng tôi thấy nỗ lực của bạn" chưa =) 15 apr. 142014-04-15 09:20:32

+12

@skiwi: Mặc dù tôi thường hét vào bài tập của tôi-thay-cho-tôi câu hỏi, câu hỏi cụ thể này dường như rõ ràng hơn với tôi mà không có thêm bất kỳ sự lộn xộn nào. Hãy giữ nó gọn gàng. 16 apr. 142014-04-16 11:21:24

692

Phương pháp dễ nhất là sử dụng phương pháp toArray(IntFunction<A[]> generator) với tham chiếu hàm tạo mảng. Điều này được đề xuất trong số API documentation for the method.

String[] stringArray = streamString.toArray(String[]::new); 

gì nó làm, là tìm một phương pháp mà mất trong một số nguyên (kích thước) như là đối số, và trả về một String[], đó là chính xác những gì (một trong những định nghĩa chồng cho) new String[] làm.

Bạn cũng có thể viết riêng bạn IntFunction:

Stream<String> stream = ...; 
String[] stringArray = stream.toArray(size -> new String[size]); 

Mục đích của IntFunction<A[]> generator là để chuyển đổi một số nguyên, kích thước của mảng, một mảng mới.

Ví dụ mã:

Stream<String> streamString = Stream.of("a", "b", "c"); 
String[] stringArray = streamString.toArray(size -> new String[size]); 
Arrays.stream(stringArray).forEach(System.out::println); 

Prints:

a 
b 
c 
+176

'String [] :: new' là một mẹo hay; đơn giản hơn biểu thức lambda, theo ý kiến ​​của tôi. 18 dec. 142014-12-18 07:55:54

+11

Zenexer đúng, giải pháp phải là: 'stream.toArray (String [] :: new);' 01 oct. 152015-10-01 13:01:08

+4

và đây là giải thích tại sao và cách tham chiếu hàm tạo của mảng thực sự hoạt động: http://stackoverflow.com/ câu hỏi/29447561/how-do-java-8-array-constructor-references-work 12 sep. 162016-09-12 18:16:38

  0

* "Zenexer là đúng, giải pháp nên là: stream.toArray (String [] :: new);" * ... Vâng ok , nhưng ta nên hiểu rằng tham chiếu phương thức là logic và chức năng tương đương với 'toArray (sz -> new String [sz])' vì vậy tôi không chắc chắn rằng một thực sự có thể nói những gì các giải pháp nên hoặc phải. 20 apr. 172017-04-20 14:16:02

  0

Tham khảo hàm tạo mảng là ngắn gọn hơn. Tài liệu cho phương thức 'toArray()' trích dẫn phương thức của nó và bao gồm việc sử dụng nó trong ví dụ duy nhất. Khi nó được tacked vào cuối của câu trả lời, tôi bị mất nó trên đọc đầu tiên. Di chuyển nó lên đầu, phía trên các chi tiết, để không ai khác sẽ bỏ lỡ nó. 01 may. 172017-05-01 19:44:05

+2

@scottb 'sz -> chuỗi mới [sz]' tạo một hàm mới khi tham chiếu hàm tạo không. Nó phụ thuộc vào việc bạn đánh giá Garbage Collection Churn như thế nào. 18 aug. 172017-08-18 09:19:42

+1

@WORMSS Nó không. Nó (tĩnh!) Làm cho một phương thức 'private' * mới, không thể gây ra sự lộn xộn, và cả hai phiên bản * cần tạo một đối tượng mới. Một tham chiếu tạo ra một đối tượng trỏ trực tiếp vào phương thức đích; lambda tạo một đối tượng trỏ vào một 'private'. Một tham chiếu đến một nhà xây dựng vẫn nên thực hiện tốt hơn vì thiếu sự gián tiếp và tối ưu hóa VM dễ dàng hơn, nhưng không có gì phải làm với nó. 29 oct. 172017-10-29 23:54:01

  0

@HTNW bạn là chính xác, xin lỗi của tôi. Nó đã được infact của tôi cố gắng để gỡ lỗi đó đã gây ra khuấy đã gây ra khuấy động lần đầu tiên tôi đã cố gắng để làm điều này, vì vậy tôi đã có nó bị mắc kẹt trong đầu của tôi rằng đây là như thế nào. (Ghét nó khi điều đó xảy ra). 30 oct. 172017-10-30 08:38:59


17

Nếu bạn muốn nhận được một mảng ints, bằng giá trị dạng 1 đến 10, từ một Stream, có IntStream theo ý của bạn .

Ở đây chúng tôi tạo Luồng bằng phương thức Stream.of và chuyển đổi Luồng sang IntStream bằng cách sử dụng mapToInt. Sau đó chúng ta có thể gọi phương thức toArray của IntStream.

Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9,10); 
//or use this to create our stream 
//Stream<Integer> stream = IntStream.rangeClosed(1, 10).boxed(); 
int[] array = stream.mapToInt(x -> x).toArray(); 

Đây là điều tương tự, mà không Luồng, chỉ sử dụng các IntStream

int[]array2 = IntStream.rangeClosed(1, 10).toArray(); 

2

Bạn có thể tạo một nhà sưu tập tùy chỉnh mà chuyển đổi một dòng để mảng.

public static <T> Collector<T, ?, T[]> toArray(IntFunction<T[]> converter) 
{ 
    return Collectors.collectingAndThen( 
        Collectors.toList(), 
        list ->list.toArray(converter.apply(list.size()))); 
} 

và sử dụng nhanh chóng

List<String> input = Arrays.asList(.....); 

String[] result = input.stream(). 
     .collect(CustomCollectors.**toArray**(String[]::new)); 

0
 Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6); 

    Integer[] integers = stream.toArray(it->new Integer[it]); 

0

Bạn có thể chuyển đổi một dòng java 8 đến một mảng sử dụng khối này mã đơn giản:

String[] myNewArray3 = myNewStream.toArray(String[]::new); 

Nhưng chúng ta hãy giải thích điều hơn, trước tiên, hãy tạo danh sách chuỗi chứa ba giá trị:

String[] stringList = {"Bachiri","Taoufiq","Abderrahman"}; 

Tạo một dòng suối từ Array đưa ra:

Stream<String> stringStream = Arrays.stream(stringList); 

bây giờ chúng tôi có thể thực hiện một số hoạt động vào hoạt động này Ex:

Stream<String> myNewStream = stringStream.map(s -> s.toUpperCase()); 

và cuối cùng là chuyển nó sang một java 8 mảng sử dụng các phương pháp :

Phương thức 1 cổ điển (Giao diện chức năng)

IntFunction<String[]> intFunction = new IntFunction<String[]>() { 
    @Override 
    public String[] apply(int value) { 
     return new String[value]; 
    } 
}; 


String[] myNewArray = myNewStream.toArray(intFunction); 

2 -Lambda biểu

String[] myNewArray2 = myNewStream.toArray(value -> new String[value]); 

3- Phương pháp tham khảo

String[] myNewArray3 = myNewStream.toArray(String[]::new); 

Phương pháp tham khảo Giải thích:

Đó là một cách khác để viết một biểu thức lambda rằng đó là đúng tương đương với người kia.


2

Sử dụng phương pháp toArray(IntFunction<A[]> generator) thực sự là một cách rất thanh lịch và an toàn để chuyển đổi (hoặc chính xác hơn, thu thập) Luồng vào một mảng cùng loại Luồng.

Tuy nhiên, nếu loại mảng được trả về không quan trọng, chỉ cần sử dụng phương pháp toArray() là cả hai ngắn hơn dễ dàng hơn . Ví dụ:

Stream<Object> args = Stream.of(BigDecimal.ONE, "Two", 3); 
    System.out.printf("%s, %s, %s!", args.toArray());