Xử lý và chuyển đổi dòng dữ liệu với Guava trong Spring

Trong phát triển hiện đại, việc xử lý và chuyển đổi dòng dữ liệu là yêu cầu rất phổ biến. Từ việc đọc dữ liệu từ tệp, nhận đầu vào của người dùng, đến trích xuất thông tin từ cơ sở dữ liệu, dữ liệu thường cần trải qua nhiều bước chuyển đổi và xử lý. Thư viện Guava cung cấp nhiều công cụ và lớp giúp đơn giản hóa quy trình này, đặc biệt là khi kết hợp các thao tác theo phong cách chuỗi (chain), giúp xử lý dòng dữ liệu rõ ràng và thanh lịch hơn.

1. FluentIterable của Guava: Xử lý dòng dữ liệu bằng chuỗi

FluentIterable là phiên bản nâng cao của Iterable mà Guava cung cấp. Nó mở rộng giao diện Iterable, cho phép nhà phát triển thực hiện các thao tác chuỗi một cách thanh lịch trên tập hợp dữ liệu. FluentIterable bao gồm nhiều phương thức thao tác dòng phổ biến, giúp tăng cường khả năng đọc và bảo trì mã nguồn.

DataProcessor<String> names = FluentIterable.from(Lists.newArrayList("John", "Jane", "Adam", "Tom"))
    .filter(name -> name.startsWith("J"))
    .transform(String::toUpperCase);

Trong ví dụ trên, chúng ta tạo một đối tượng FluentIterable, sau đó áp dụng hai thao tác dòng:

  1. filter(): Loại bỏ tên không bắt đầu bằng chữ cái "J".
  2. transform(): Chuyển tất cả tên thành chữ in hoa.

Phong cách chuỗi giúp loại bỏ nhu cầu sử dụng nhiều biến tạm thời, làm mã ngắn gọn hơn.

2. Sử dụng Iterables để xử lý dòng dữ liệu

Lớp Iterables của Guava là công cụ thường được sử dụng để xử lý dữ liệu dạng Iterable. Đặc biệt hữu ích khi làm việc với khối lượng lớn dữ liệu dòng, Iterables cung cấp nhiều phương thức tiện lợi để lọc, ánh xạ và chia nhỏ dữ liệu.

Ví dụ, chúng ta có thể sử dụng Iterables.transform() để chuyển đổi từng phần tử trong tập hợp:

Iterable<String> names = Lists.newArrayList("John", "Jane", "Adam", "Tom");
Iterable<String> upperCaseNames = Iterables.transform(names, String::toUpperCase);
for (String name : upperCaseNames) {
    System.out.println(name);
}

Ở đây, chúng ta đã sử dụng Iterables.transform() để chuyển đổi mỗi phần tử trong tập hợp thành chữ in hoa, làm cho việc chuyển đổi dữ liệu tập hợp trở nên đơn giản và dễ hiểu.

3. Lớp Joiner: Kết nối chuỗi dễ dàng

Khi xử lý dữ liệu, việc ghép nối nhiều chuỗi lại với nhau là điều thường xuyên xảy ra. Lớp Joiner cung cấp giải pháp hiệu quả cho nhu cầu này. Joiner có thể ghép nối các phần tử trong tập hợp bằng ký tự phân cách chỉ định và cũng cung cấp tùy chọn xử lý giá trị null.

List<String> names = Lists.newArrayList("John", "Jane", "Adam", null, "Tom");
// Ghép nối tập hợp thành một chuỗi duy nhất và bỏ qua giá trị null
String result = Joiner.on(", ").skipNulls().join(names);
System.out.println(result);

Kết quả đầu ra:

John, Jane, Adam, Tom

Ngoài ra, Joiner còn có thể thay thế giá trị null bằng chuỗi mặc định:

String resultWithDefault = Joiner.on(", ").useForNull("Unknown").join(names);
System.out.println(resultWithDefault);

Kết quả đầu ra:

John, Jane, Adam, Unknown, Tom

Với Joiner, chúng ta có thể đơn giản hóa quá trình ghép nối chuỗi và tránh phải xử lý phức tạp giá trị null.

4. Lớp Splitter: Phân tách chuỗi linh hoạt

Splitter là công cụ của Guava dùng để phân tách chuỗi, tương tự như phương thức String.split() trong Java nhưng linh hoạt hơn. Splitter cho phép bạn phân tách chuỗi dựa trên ký tự hoặc biểu thức chính quy chỉ định, đồng thời hỗ trợ loại bỏ khoảng trắng và chuỗi rỗng.

Ví dụ, sử dụng Splitter để xử lý chuỗi có nhiều ký tự phân cách khác nhau:

String input = "apple,banana;orange,grape";
Iterable<String> fruits = Splitter.onPattern("[,;]").split(input);
for (String fruit : fruits) {
    System.out.println(fruit);
}

Kết quả đầu ra:

apple
banana
orange
grape

Splitter cũng có thể giúp loại bỏ khoảng trắng dư thừa:

String inputWithSpaces = "apple, banana, orange";
Iterable<String> fruitsNoSpaces = Splitter.on(",").trimResults().split(inputWithSpaces);
for (String fruit : fruitsNoSpaces) {
    System.out.println(fruit);
}

Kết quả đầu ra:

apple
banana
orange

Nhờ vậy, chúng ta có thể dễ dàng xử lý chuỗi có khoảng trắng hoặc nhiều ký tự phân cách mà không cần lo lắng về các chi tiết phức tạp.

5. Chuỗi thao tác dòng và hợp nhất

Trong ứng dụng thực tế, dòng dữ liệu thường cần trải qua nhiều bước xử lý. Các lớp công cụ của Guava như FluentIterable, Iterables, Joiner, và Splitter rất phù hợp để thực hiện các thao tác dòng. Bằng cách sử dụng phong cách chuỗi, chúng ta có thể thực hiện loạt chuyển đổi và xử lý dữ liệu mà không cần tạo thêm các biến tạm thời.

String input = "apple,,banana,,,orange,null,";
List<String> result = Splitter.on(",")
    .omitEmptyStrings() // Loại bỏ chuỗi rỗng
    .splitToList(input)
    .stream()
    .map(String::toUpperCase) // Chuyển sang chữ in hoa
    .filter(item -> !item.equals("NULL")) // Lọc bỏ "NULL"
    .collect(Collectors.toList());
System.out.println(result);

Kết quả đầu ra:

[APPLE, BANANA, ORANGE]

Trong ví dụ này, chúng ta đã thực hiện chuỗi các thao tác: trước tiên sử dụng Splitter để phân tách chuỗi, loại bỏ chuỗi rỗng, sau đó sử dụng luồng (stream()) để chuyển đổi và lọc từng phần tử, cuối cùng thu thập chúng thành danh sách mới.

Thẻ: Guava Spring Java

Đăng vào ngày 22 tháng 7 lúc 02:57