贝利信息

如何高效地为重复名称与唯一名称的产品设置不同的 frontName 值

日期:2025-12-27 00:00 / 作者:心靈之曲

本文介绍一种基于 java stream 和 hashset 的高效方案,用于批量处理产品列表:对名称重复的产品拼接 category 名称生成 frontname,对唯一名称产品则直接赋值 name。方法时间复杂度接近 o(n),避免嵌套遍历,兼顾可读性与性能。

在实际业务开发中,我们常需根据字段的“唯一性”对对象进行差异化处理。以 Product 类为例:

@Data
public class Product {
    private UUID id;
    private String name;
    private String categoryName;
    private String frontName;
}

目标是:
✅ 若某 name 在整个列表中出现多次 → frontName = name + "," + categoryName
✅ 若某 name 仅出现一次 → frontName = name

✅ 推荐解法:两阶段流式处理(O(n) 时间复杂度)

核心思路:先识别所有重复 name,再统一更新。利用 Set.add() 返回值(false 表示已存在)在单次遍历中收集重复项:

// 第一阶段:提取所有重复的 product name
Set seen = new HashSet<>();
Set duplicateNames = productList.stream()
        .map(Product::getName)
        .filter(name -> !seen.add(name))  // add() 返回 false → 已存在 → 是重复项
        .collect(Collectors.toSet());

// 第二阶段:遍历原列表,按重复性设置 frontName
productList.forEach(product -> {
    if (duplicateNames.contains(product.getName())) {
        product.setFrontName(product.getName() + "," + product.getCategoryName());
    } else {
        product.setFrontName(product.getName());
    }
});
? 关键点说明: seen.add(name) 在首次遇到 name 时返回 true,后续重复调用返回 false; filter(...) 保留的是所有 第二次及以后出现 的 name,因此 duplicateNames 准确涵盖所有重复值; 整体仅需两次线性遍历(Stream + forEach),无嵌套循环,性能稳定。

⚠️ 注意事项与优化建议

该方案简洁、高效、易维护,是处理“按字段重复性差异化赋值”类需求的典型范式。