Chuyển đổi danh sách lồng ghép thành chuỗi định dạng bằng StringBuilder trong Java

Trong các ứng dụng quản lý vật tư, việc biểu diễn dữ liệu từ cấu trúc phân cấp (danh sách con nằm trong đối tượng cha) dưới dạng chuỗi dễ đọc là một yêu cầu phổ biến. Bài viết này trình bày cách sử dụng StringBuilder để xây dựng trường materialNames từ danh sách formMaterialList, đảm bảo hiệu suất và tính rõ ràng.

Dữ liệu đầu vào mẫu

Dữ liệu JSON đại diện cho một đơn xin vật tư bao gồm thông tin chung và danh sách chi tiết các mặt hàng:

{
  "applicationDate": "2022-01-27 15:55:18",
  "applicationId": "d62bfc83-865b-4e0c-b2ca-63ef8df13119",
  "applicationNumber": "202201270001",
  "applicationStatus": "0",
  "approvalTime": null,
  "approvalUserName": null,
  "formMaterialList": [
    {
      "materialCount": "1",
      "materialId": "1482881601523441666",
      "materialImg": "http://192.168.0.130:80/uploadImg/2022-01-17/20220117090458165.jpg",
      "materialName": "卷尺",
      "materialSpecs": "3米",
      "materialTotalCount": "631",
      "oldMaterialCount": "1"
    },
    {
      "materialCount": "0",
      "materialId": "1482882259865591810",
      "materialImg": "http://192.168.0.130:80/uploadImg/2022-01-17/20220117090735571.jpg",
      "materialName": "撬棍",
      "materialSpecs": "3M",
      "materialTotalCount": "311",
      "oldMaterialCount": "1"
    }
  ],
  "materialFlag": "1",
  "materialNames": "卷尺:1/1,撬棍:0/1",
  "reason": null,
  "userName": "管理员"
}

Cách triển khai tối ưu

Thay vì nối chuỗi bằng toán tử + — gây tốn bộ nhớ và chậm với số lượng phần tử lớn — ta dùng StringBuilder. Đoạn mã sau xử lý danh sách formMaterialList, tạo chuỗi có định dạng "tên:đã_dùng/nguyên_bản", ngăn cách bởi dấu phẩy toàn角 (,):

if (items != null && !items.isEmpty()) {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < items.size(); i++) {
        FormMaterialAppVO item = items.get(i);
        String entry = String.format("%s:%s/%s", 
            item.getMaterialName(), 
            item.getMaterialCount(), 
            item.getOldMaterialCount());
        builder.append(entry);
        if (i < items.size() - 1) {
            builder.append(",");
        }
    }
    appVO.setMaterialNames(builder.toString());
    appVO.setFormMaterialList(items);
}

Ưu điểm của cách viết trên:

  • Loại bỏ hoàn toàn việc gọi replace() cuối chuỗi — giảm thao tác không cần thiết.
  • Sử dụng String.format() giúp dễ đọc và mở rộng hơn khi thêm trường.
  • Kiểm tra vị trí phần tử trước khi thêm dấu phân cách, tránh dư ký tự ở cuối.

Cấu trúc lớp VO liên quan

Hai lớp mô hình chính tham gia vào quá trình ánh xạ dữ liệu:

1. Lớp cha: ApplicationMaterialsAppVO

Lưu trữ thông tin tổng quan về đơn xin và danh sách vật tư chi tiết:

package com.qs.modules.applicationForm.model.vo;

import com.qs.modules.formMaterial.model.vo.FormMaterialAppVO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.List;

@Data
public class ApplicationMaterialsAppVO {
    @ApiModelProperty("ID đơn xin")
    private String applicationId;

    @ApiModelProperty("Trạng thái duyệt: 0-chưa, 1-đã duyệt, 2-từ chối")
    private String applicationStatus;

    @ApiModelProperty("Mã đơn xin")
    private String applicationNumber;

    @ApiModelProperty("Người nộp đơn")
    private String userName;

    @ApiModelProperty("Thời gian nộp")
    private String applicationDate;

    @ApiModelProperty("Người phê duyệt")
    private String approvalUserName;

    @ApiModelProperty("Thời gian phê duyệt")
    private String approvalTime;

    private String reason;

    @ApiModelProperty("Cờ có vật tư: 0-không, 1-có")
    private String materialFlag;

    @ApiModelProperty("Chuỗi tên vật tư đã định dạng")
    private String materialNames;

    private List<FormMaterialAppVO> formMaterialList;
}

2. Lớp con: FormMaterialAppVO

Mô tả thuộc tính từng mặt hàng trong đơn xin:

package com.qs.modules.formMaterial.model.vo;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
public class FormMaterialAppVO {
    @ApiModelProperty("ID vật tư")
    private String materialId;

    @ApiModelProperty("Tên vật tư")
    private String materialName;

    @ApiModelProperty("Số lượng đã sử dụng")
    private String materialCount;

    @ApiModelProperty("Số lượng ban đầu yêu cầu")
    private String oldMaterialCount;

    @ApiModelProperty("Ảnh vật tư (đường dẫn tuyệt đối)")
    private String materialImg;

    private String materialTotalCount;

    private String materialSpecs;
}

Thẻ: Java StringBuilder vo Lombok Swagger

Đăng vào ngày 10 tháng 7 lúc 14:40