Luồng Java 8 và hoạt động trên mảng


197

Tôi vừa phát hiện ra các khả năng luồng Java 8 mới. Đến từ Python, tôi đã tự hỏi liệu bây giờ có một cách gọn gàng để thực hiện các thao tác trên các mảng như tính tổng, nhân hai mảng theo cách "một dòng pythonic" không?

Cảm ơn

Câu trả lời:


294

Có các phương thức mới được thêm vào java.util.Arraysđể chuyển đổi một mảng thành luồng Java 8 mà sau đó có thể được sử dụng để tính tổng, v.v.

int sum =  Arrays.stream(myIntArray)
                 .sum();

Nhân hai mảng khó hơn một chút vì tôi không thể nghĩ ra cách lấy giá trị VÀ chỉ mục cùng lúc với thao tác Luồng. Điều này có nghĩa là bạn có thể phải truyền phát qua các chỉ mục của mảng.

//in this example a[] and b[] are same length
int[] a = ...
int[] b = ...

int[] result = new int[a.length];

IntStream.range(0, a.length)
         .forEach(i -> result[i] = a[i] * b[i]);

BIÊN TẬP

Bình luận viên @Holger chỉ ra rằng bạn có thể sử dụng mapphương pháp thay vì forEachnhư thế này:

int[] result = IntStream.range(0, a.length).map(i -> a[i] * b[i]).toArray();

13
int[] result=IntStream.range(0, a.length).map( i->a[i]* b[i]).toArray();
Holger

2
@Holger có mà cũng sẽ làm việc. Mặc dù bạn có thể muốn sử dụng mapToIntđể tránh đấm bốc.
dkatzel

Đó là số tiền cuối cùng cho một mô phỏng của zip nơi bạn phải phân bổ lưu trữ cho kết quả. Tôi tự hỏi tại sao không có zip trong thư viện Streams?
Reb.Cabin

Theo câu trả lời SO này , một zip đã ở phiên bản beta trước đó của Java 8, sau đó được lấy ra. May mắn là áp phích có nguồn và nó là trong câu trả lời. Tôi đã sử dụng mã nhiều lần và nó dường như hoạt động rất tốt.
sparc_s Lan

@dkatzel - Vì nó đã là IntStream, "map" cần một IntUnaryOperator, do đó không có quyền anh tham gia.
M. Justin

58

Bạn có thể biến một mảng thành một luồng bằng cách sử dụng Arrays.stream():

int[] ns = new int[] {1,2,3,4,5};
Arrays.stream(ns);

Khi bạn đã có luồng của mình, bạn có thể sử dụng bất kỳ phương pháp nào được mô tả trong tài liệu , như sum()hoặc bất cứ điều gì. Bạn có thể maphoặc filterthích trong Python bằng cách gọi các phương thức luồng có liên quan bằng hàm Lambda:

Arrays.stream(ns).map(n -> n * 2);
Arrays.stream(ns).filter(n -> n % 4 == 0);

Khi bạn hoàn tất sửa đổi luồng của mình, sau đó bạn gọi toArray()để chuyển đổi lại thành một mảng để sử dụng ở nơi khác:

int[] ns = new int[] {1,2,3,4,5};
int[] ms = Arrays.stream(ns).map(n -> n * 2).filter(n -> n % 4 == 0).toArray();

9

Hãy cẩn thận nếu bạn phải đối phó với số lượng lớn.

int[] arr = new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE};
long sum = Arrays.stream(arr).sum(); // Wrong: sum == 0

Số tiền trên không phải là 2 * Integer.MIN_VALUE. Bạn cần phải làm điều này trong trường hợp này.

long sum = Arrays.stream(arr).mapToLong(Long::valueOf).sum(); // Correct

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.