Làm cách nào để chuyển đổi Luồng Java 8 thành Mảng?


775

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


2
Tôi đề nghị bạn nên hoàn nguyên các rollback vì câu hỏi đã hoàn thiện hơn và cho thấy bạn đã thử điều gì đó.
skiwi

2
@skiwi Cảm ơn! nhưng tôi nghĩ rằng mã đã thử không thực sự bổ sung thêm thông tin cho câu hỏi và không ai hét lên "hãy cho chúng tôi thấy nỗ lực của bạn" =)

17
@skiwi: Mặc dù tôi thường hét vào những câu hỏi làm bài tập thay vì tôi, nhưng câu hỏi đặc biệt 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.
Honza Zidek

Bạn có thể tìm thấy rất nhiều câu trả lời và hướng dẫn trong các tài liệu chính thức của gói: docs.oracle.com/javase/8/docs/api/java/util/stream/iêu
Roussy

Câu trả lời:


1168

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

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

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

Bạn cũng có thể tự viết IntFunction:

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

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

Mã ví dụ:

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

Bản in:

a
b
c

8
và đây là một lời giải thích tại sao và làm thế nào tham chiếu của hàm tạo Array thực sự hoạt động: stackoverflow.com/questions/29447561/
mẹo

"Zenexer đã đúng, giải pháp nên là: stream.toArray (String [] :: new);" ... Tốt thôi, nhưng người ta nên hiểu rằng tham chiếu phương thức là tương đương về mặt logic và chức năng toArray(sz -> new String[sz])vì vậy tôi không chắc rằng người ta thực sự có thể nói giải pháp nên hay phải là gì.
scottb

3
@scottb sz -> new String[sz]tạo một hàm mới trong đó tham chiếu của hàm tạo không có. Nó phụ thuộc vào mức độ bạn đánh giá Rác Bộ sưu tập Churn tôi đoán.
CÔNG TRÌNH 18/8/17

3
@WORMSS Không. Nó (tĩnh!) Tạo ra một private phương thức mới, không thể gây ra sự khuấy động 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 ra một đối tượng trỏ vào đối tượng được tạo private. Một tham chiếu đến một nhà xây dựng vẫn nên hoạt động 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 việc khuấy đảo không liên quan gì đến nó.
HTNW

2
@HTNW bạn đúng rồi, tôi xin lỗi. Đó là nguyên nhân của nỗ lực gỡ lỗi của tôi đã gây ra vụ nổ gây ra vụ nổ lần đầu tiên khi tôi cố gắng làm điều này, vì vậy tôi đã bị mắc kẹt trong đầu rằng đây là cách nó diễn ra. (Ghét nó khi điều đó xảy ra).
CÔNG TRÌNH

41

Nếu bạn muốn có được một mảng các số nguyên, với các giá trị từ 1 đến 10, từ Luồng, 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 thành IntStream bằ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ự, không có Stream, chỉ sử dụng IntStream

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

15

Bạn có thể chuyển đổi luồng java 8 thành một mảng bằng cách sử dụng khối mã đơn giản này:

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

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

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

Tạo một luồng từ Mảng đã cho:

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

bây giờ chúng ta có thể thực hiện một số thao tác trên luồng này Ex:

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

và cuối cùng chuyển đổi nó thành java 8 Array bằng các phương thức sau:

Phương pháp 1-Classic (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 thức

 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 nó hoàn toàn tương đương với cách khác.


6

Chuyển đổi văn bản thành mảng chuỗi trong đó phân tách từng giá trị bằng dấu phẩy và cắt mọi trường, ví dụ:

String[] stringArray = Arrays.stream(line.split(",")).map(String::trim).toArray(String[]::new);

4

Bạn có thể tạo một trình thu thập tùy chỉnh để chuyển đổi một luồng thành 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 ) );

5
Tại sao bạn lại sử dụng cái này thay vì Stream.toArray (IntFunction) ?
Didier L

Tôi cần một bộ sưu tập để chuyển đến 2-arg Collectors.groupingByđể tôi có thể ánh xạ một số thuộc tính thành các mảng của các đối tượng trên mỗi giá trị thuộc tính. Câu trả lời này cho tôi chính xác điều đó. Ngoài ra @DidierL.
Ole VV

3

Sử dụng toArray(IntFunction<A[]> generator) phương thức này 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 là thu thập) một luồng thành một mảng cùng loại của Luồng.

Tuy nhiên, nếu kiểu của mảng trả về không quan trọng, chỉ cần sử dụng toArray()phương thức vừa dễ hơn vừa ngắn hơn. Ví dụ:

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

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

int[] arr=   stream.mapToInt(x->x.intValue()).toArray();

0
import java.util.List;
import java.util.stream.Stream;

class Main {

    public static void main(String[] args) {
        // Create a stream of strings from list of strings
        Stream<String> myStreamOfStrings = List.of("lala", "foo", "bar").stream();

        // Convert stream to array by using toArray method
        String[] myArrayOfStrings = myStreamOfStrings.toArray(String[]::new);

        // Print results
        for (String string : myArrayOfStrings) {
            System.out.println(string);
        }
    }
}

Dùng thử trực tuyến: https://repl.it/@SmaMa/Stream-to-array


Sự khác biệt giữa câu trả lời của bạn và câu trả lời được chấp nhận là gì?
Long Nguyên

@LongNguyen Đó là một ví dụ đầy đủ bao gồm một kịch bản phát lại trực tuyến, không chỉ là một đoạn trích.
Sma Ma

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

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

-2

Bạn có thể làm điều đó theo một số cách. Tất cả các cách đều giống nhau về mặt kỹ thuật nhưng sử dụng Lambda sẽ đơn giản hóa một số mã. Hãy nói rằng chúng tôi khởi tạo Danh sách trước bằng Chuỗi, gọi nó là người.

List<String> persons = new ArrayList<String>(){{add("a"); add("b"); add("c");}};
Stream<String> stream = persons.stream();

Bây giờ bạn có thể sử dụng một trong những cách sau.

  1. Sử dụng Lambda Expresiion để tạo StringArray mới với kích thước được xác định.

    Chuỗi [] stringArray = stream.toArray (size-> new String [size]);

  2. Sử dụng phương pháp tham khảo trực tiếp.

    Chuỗi [] stringArray = stream.toArray (Chuỗi [] :: new);

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.