Biểu thức Lambda và Stream trong Java 8

Java 8 giới thiệu nhiều tính năng mới nổi bật, trong đó nổi bật nhất là Stream API - một công cụ mạnh mẽ để xử lý tập dữ liệu. Stream API cung cấp cách tiếp cận hiện đại và ngắn gọn hơn cho các thao tác trên collection, ví dụ như sắp xếp một Map dựa trên giá trị của nó.

Trước đây, chúng ta thường chuyển Map thành List<Entry> và sử dụng phương thức sắp xếp của list, nhưng với Stream API, code trở nên gọn gàng và dễ đọc hơn.

public static <K, V extends Comparable<? super V>> Map<K, V> sapXepTheoGiaTri(Map<K, V> duLieu) {
        Map<K, V> ketQua = new LinkedHashMap<>();
        Stream<Map.Entry<K, V>> luong = duLieu.entrySet().stream();
        luong.sorted(Comparator.comparing(e -> e.getValue()))
           .forEach(e -> ketQua.put(e.getKey(), e.getValue()));
        return ketQua;
   }

// Ví dụ khác: tính tổng trọng lượng của các widget màu đỏ
int tong = danhSachWidget.stream()
     .filter(w -> w.getMauSac() == DO)
     .mapToInt(w -> w.getTrongLuong())
     .sum();

Khi làm việc với Map, phương thức map.entrySet() trả về một tập hợp các cặp khóa-giá trị, với mỗi phần tử là kiểu Map.Entry<K, V>. Chúng ta có thể sử dụng getKey() và getValue() để truy cập các giá trị này.

Tiếp theo, hãy tìm hiểu về Generics trong Java. Định nghĩa lớp generic khá đơn giản, nhưng chúng ta cần chú ý đến phương thức generic: cụ thể kiểu generic khi gọi phương thức.

/**
* Giới thiệu về phương thức generic
* @param lopLop Lớp generic được truyền vào
* @return T Trả về đối tượng kiểu T
* Giải thích:
* 1) Phần <T> giữa public và kiểu trả về rất quan trọng, khai báo đây là phương thức generic.
* 2) Chỉ những phương thức được khai báo với <T> mới là phương thức generic.
* 3) <T> cho biết phương thức sẽ sử dụng kiểu generic T.
* 4) T có thể thay bằng bất kỳ ký tự nào, thường dùng T, E, K, V để biểu thị generic.
*/
public <T> T phuongThucGeneric(Class<T> lopLop) 
       throws InstantiationException, IllegalAccessException{
  T doiTuong = lopLop.newInstance();
  return doiTuong;
}

Trong lớp generic, sự khác biệt giữa <T extends Comparable<T>><T extends Comparable<? super T>> nằm ở mức độ giới hạn. Câu lệnh đầu tiên giới hạn chặt chẽ hơn so với câu thứ hai. Ví dụ với GregorianCalendar, <T extends Comparable<T>> tương đương với <GregorianCalendar extends Comparable<GregorianCalendar>>, nhưng thực tế GregorianCalendar implements Comparable<Calendar> chứ không phải Comparable<GregorianCalendar>. Thiết kế này giúp tránh trùng lặp mã nguồn.

Về biểu thức chính quy trong Java, chúng ta chủ yếu làm việc với hai lớp Pattern và Matcher. Pattern được sử dụng để định nghĩa mẫu khớp, trong khi Matcher thực hiện việc kiểm tra khớp với chuỗi đầu vào.

// Ví dụ xử lý profile trong Spring
this.setActiveProfiles(StringUtils.commaDelimitedListToStringArray(
    StringUtils.trimAllWhitespace(profiles)));

Java 8 giới thiệu các lớp thời gian mới như Instant và LocalDateTime, cung cấp nhiều API hữu ích và hỗ trợ thao tác với múi giờ. Tuy nhiên, khi sử dụng fastJson, có sự khác biệt trong cách định dạng: Date được chuyển thành số, trong khi Instant và LocalDateTime thành chuỗi. Cần lưu ý điều này khi cần định dạng.

Tham khảo: <<Effective Java>>

Biểu thức chính quy Java

Thẻ: Java 8 Stream API Lambda Generics Date Time API

Đăng vào ngày 6 tháng 6 lúc 19:51