Menu

Java 8: Có nên sử dụng filter của Stream API

Java 8 giới thiệu rất nhiều tính năng mới. Trong đó Stream (luồng) cũng là một tính năng cực kỳ hữu ích và được sử dụng thường xuyên (kết hợp với biểu thức Lambda).

Cụ thể Stream là gì? Nó là một đối tượng mới của Java được giới thiệu từ phiên bản Java 8, giúp cho việc thao tác trên danh sách (collection) và mảng (array) trở nên dễ dàng và tối ưu hơn.

Một Stream đại diện cho một chuỗi các phần tử hỗ trợ các hoạt động tổng hợp tuần tự (sequential) và song song (parallel).

Các thao tác của Stream API

Có thể thấy ngay trong định nghĩa Stream có thể giúp chúng ta thao tác trên danh sách và mảng dễ dàng, tối ưu. Ngoài ra, bản thân tôi nhận thấy sử dụng  Stream khiến cho code ngắn gọn và dễ đọc hơn rất nhiều.

Tuy nên, trong quá trình review code của cả những người có kinh nghiệm ( > 5-7 năm) hoặc không có tôi vấn thấy họ không tận dụng hết những tính năng ưu việt này. Sau khi trao đổi với họ, tôi nhận ra rằng bản thân họ đã quá quen với cách viết của Java 7 nên việc chuyển qua cách viết mới của Java 8 chưa quen, đồng thời họ muốn công việc trôi.

Trong bài viết này, tôi lấy ví dụ: có một danh sách các số tự nhiên (0 ... n). Tôi muốn lấy ra danh sách các số chẵn. Tôi sẽ triển khai 2 phong cách code (Java 7 và Java 8), rồi đưa ra một so sánh nho nhỏ:

Phong cách Java 7:

List<Long> longs; //A list
List<Long> result = new ArrayList<>();
for (long lValue : longs) {
if (lValue % 2 == 0) {
result.add(lValue);
}
}

Phong cách Java 8:

List<Long> longs; //A list
List<Long> result = longs.stream()
.filter(lValue -> lValue % 2 == 0)
.collect(Collectors.toList());

Trước tiên, tôi muốn bạn nói về cảm nhận của mình? Hai đoạn code trên điều cho cùng một kết quả (một danh sách số nguyên chẵn). Nhưng bạn thấy cách nào dễ hiểu, tự nhiên và dễ hiểu hơn? (Tuỳ bạn đánh giá).

Cái tôi có thể đo đếm được (không dựa vào cảm tính) là thời gian thực hiện và lượng bộ nhớ sử dụng. Tôi thực hiện chạy ứng dụng với kích thước đầu vào là 100, 1000, 10000, 100000, 100000 và được kết quả như sau:

Thời gian thực hiện

Biểu đồ cho thấy, thời gian xử lý theo phong cách Java 7 tăng nhanh hơn so với Java 8 khi kích thước đầu vào tăng lên. Tuy nhiên, với số lượng đầu vào ít (ví dụ: < 1000000) thì chênh lệch không đáng kể.

Bộ nhớ sử dụng

Đối với bộ nhớ sử dụng, chúng ta thấy có sự trái ngược so với thời gian thực nghĩa. Nghĩa là bộ nhớ sử dụng theo phong cách Java 7 tăng chậm hơn so với Java tam khi kích thước đầu vào tăng lên. Điều này cũng là hợp lý vì được cái này mất cái kia.

Kết luận

Với 2 so sách như trên, chúng ta hoàn toàn có lý do để bảo vệ phong cách viết code của mình (phong cách Java 7 hoặc Java 8). Nhưng theo tôi, phiên bản sau luôn có những cái tiến tốt hơn phiên bản trước và cách viết code của Java 8 cũng tự nhiên và dễ đọc hơn.

Tùy vào hoàn cảnh, khả năng, sở thích bạn có thể chọn phong cách của riêng mình và theo tôi nên giữ nó thống nhất trong toàn bộ dự án.

Không có nhận xét nào:

Đăng nhận xét