package com.vincent.rsf.server.manager.utils;
|
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.google.gson.JsonObject;
|
import lombok.Data;
|
|
import java.util.*;
|
import java.util.function.BinaryOperator;
|
import java.util.function.Function;
|
import java.util.stream.Collectors;
|
|
/**
|
* @author Ryan
|
* @description 根据对象多个属性合并处理
|
* @param
|
* @return
|
* @time 2025/4/25 10:55
|
*/
|
public class GroupMergeUtil {
|
/**
|
* 根据多个属性分组合并对象列表
|
*
|
* @param list 待分组的对象列表
|
* @param mergers 合并函数,定义如何合并同一组中的对象
|
* @param keyGetters 分组属性的getter方法数组
|
* @param <T> 对象类型
|
* @param <K> 分组键类型
|
* @return 分组合并后的对象列表
|
*/
|
@SafeVarargs
|
public static <T, K> List<T> groupAndMerge(
|
List<T> list,
|
BinaryOperator<T> mergers,
|
Function<T, K>... keyGetters) {
|
|
return new ArrayList<>(list.stream()
|
.collect(Collectors.toMap(
|
item -> new GroupingKeys<>(Arrays.stream(keyGetters)
|
.map(getter -> getter.apply(item))
|
.toArray()),
|
Function.identity(),
|
mergers))
|
.values());
|
}
|
|
/**
|
* @author Ryan
|
* @description 用于存储多个分组键的内部类
|
* @param
|
* @return
|
* @time 2025/4/25 10:56
|
*/
|
private static class GroupingKeys<K> {
|
private final Object[] keys;
|
private final int hashCode;
|
|
public GroupingKeys(Object[] keys) {
|
this.keys = keys;
|
this.hashCode = Arrays.deepHashCode(keys);
|
}
|
|
@Override
|
public boolean equals(Object o) {
|
if (this == o) {
|
return true;
|
}
|
if (o == null || getClass() != o.getClass()) {
|
return false;
|
}
|
GroupingKeys<?> that = (GroupingKeys<?>) o;
|
return Arrays.deepEquals(keys, that.keys);
|
}
|
|
@Override
|
public int hashCode() {
|
return hashCode;
|
}
|
}
|
|
// 示例使用
|
// public static void main(String[] args) {
|
// // 示例数据类
|
// @Data
|
// class Product {
|
// private String category;
|
// private String subCategory;
|
// private String abc;
|
//
|
// private String dbc;
|
//
|
// private String brand;
|
// private int quantity;
|
// private double price;
|
//
|
// public Product(String category, String abc, String dbc, String subCategory, String brand, int quantity, double price) {
|
// this.category = category;
|
// this.subCategory = subCategory;
|
// this.abc = abc;
|
// this.dbc = dbc;
|
// this.brand = brand;
|
// this.quantity = quantity;
|
// this.price = price;
|
// }
|
//
|
// // getters...
|
//// public String getCategory() { return category; }
|
//// public String getSubCategory() { return subCategory; }
|
//// public String getBrand() { return brand; }
|
//// public int getQuantity() { return quantity; }
|
//// public double getPrice() { return price; }
|
//
|
// @Override
|
// public String toString() {
|
// return String.format("[%s, %s, %s] - Qty: %d, Price: %.2f",
|
// category, subCategory, brand, quantity, price);
|
// }
|
// }
|
//
|
// // 创建测试数据
|
// List<Product> products = Arrays.asList(
|
// new Product("Electronics", "Phone", "Apple", 10, 999.99),
|
// new Product("Electronics", "Phone", "Samsung", 15, 899.99),
|
// new Product("Electronics", "Phone", "Apple", 5, 999.99),
|
// new Product("Electronics", "Tablet", "Apple", 8, 799.99),
|
// new Product("Clothing", "Shirt", "Nike", 20, 29.99),
|
// new Product("Clothing", "Shirt", "Nike", 10, 29.99),
|
// new Product("Clothing", "Pants", "Adidas", 12, 49.99)
|
// );
|
//
|
// // 按 category, subCategory, brand 分组,合并 quantity 相加,price 取平均值
|
// List<Product> mergedProducts = groupAndMerge(
|
// products,
|
// (p1, p2) -> new Product(
|
// p1.category,
|
// p1.subCategory,
|
// p1.brand,
|
// p1.quantity + p2.quantity,
|
// (p1.price + p2.price) / 2 // 这里简单平均,实际业务可能不同
|
// ),
|
// Product::getCategory,
|
// Product::getSubCategory,
|
// Product::getBrand
|
// );
|
//
|
//// // 打印结果
|
//// System.out.println("合并后的产品列表:");
|
//// System.out.println(JSONArray.toJSONString(mergedProducts));
|
//// mergedProducts.forEach(item -> {
|
//// System.out.println(JSONObject.toJSONString(item));
|
//// });
|
//// mergedProducts.forEach(System.out::println);
|
// }
|
}
|