优先级计算

parent c4a85650
......@@ -8,24 +8,19 @@ import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 增强版订单排序服务(结合配置化排序器)
* 支持基于配置规则的动态排序和优先级分配
* 增强版订单排序服务(最终版:严格匹配条件数格式)
*/
@Slf4j
@Service
public class OrderSortService {
// 默认优先级基数
private static final double DEFAULT_BASE_PRIORITY = 1.0;
// 默认优先级范围
private static final double DEFAULT_LEVEL_RANGE = 1.0;
// 字段提取器映射(静态常量,所有实例共享)
private static final Map<String, Function<Order, ?>> FIELD_EXTRACTORS = new HashMap<>();
......@@ -37,13 +32,16 @@ public class OrderSortService {
registerFieldExtractor("id", Order::getId);
registerFieldExtractor("productId", Order::getProductId);
registerFieldExtractor("quantity", Order::getQuantity);
registerFieldExtractor("dueDate", Order::getDueDate);
registerFieldExtractor("dueDate", Order -> {
// 直接返回LocalDate,处理null情况
return Optional.ofNullable(Order.getDueDate())
.map(OffsetDateTime::toLocalDate)
.orElse(null);
});
registerFieldExtractor("priority", Order::getPriority);
registerFieldExtractor("tardiness", Order::getTardiness);
registerFieldExtractor("canSplit", Order::isCanSplit);
registerFieldExtractor("canInterrupt", Order::isCanInterrupt);
// 可以在这里加载扩展的字段提取器
}
/**
......@@ -66,8 +64,6 @@ public class OrderSortService {
}
List<Order> sortedOrders = assignPriorityValues(new ArrayList<>(orders), rule);
// 更新原列表
orders.clear();
orders.addAll(sortedOrders);
}
......@@ -88,20 +84,14 @@ public class OrderSortService {
return new ArrayList<>(orders);
}
// 按条件顺序排序
List<OrderSortRule.SortCondition> sortedConditions = rule.getConditions().stream()
.sorted(Comparator.comparingInt(OrderSortRule.SortCondition::getSequence))
.collect(Collectors.toList());
// 构建比较器链
Comparator<Order> comparator = null;
for (OrderSortRule.SortCondition condition : sortedConditions) {
Comparator<Order> currentComparator = createConditionComparator(condition);
if (comparator == null) {
comparator = currentComparator;
} else {
comparator = comparator.thenComparing(currentComparator);
}
comparator = comparator == null ? currentComparator : comparator.thenComparing(currentComparator);
}
return orders.stream()
......@@ -110,7 +100,7 @@ public class OrderSortService {
}
/**
* 分配多级优先级数值
* 分配层级化序号式优先级(严格匹配条件数格式)
*/
public List<Order> assignPriorityValues(List<Order> orders, OrderSortRule rule) {
Objects.requireNonNull(orders, "Orders list must not be null");
......@@ -124,76 +114,103 @@ public class OrderSortService {
return new ArrayList<>(orders);
}
// 按条件顺序排序(sequence越小越先执行)
List<OrderSortRule.SortCondition> sortedConditions = rule.getConditions().stream()
.sorted(Comparator.comparingInt(OrderSortRule.SortCondition::getSequence))
.collect(Collectors.toList());
// 递归分配优先级
assignPriorityRecursive(orders, sortedConditions, 0, DEFAULT_BASE_PRIORITY, DEFAULT_LEVEL_RANGE);
// 为每个订单初始化优先级路径
Map<Order, List<Integer>> priorityPaths = new HashMap<>();
orders.forEach(order -> priorityPaths.put(order, new ArrayList<>()));
// 递归分配层级化优先级(核心逻辑)
assignHierarchicalPriority(orders, sortedConditions, 0, priorityPaths);
// 按优先级排序
// 将路径转换为最终格式
convertPriorityPathsToNumeric(orders, priorityPaths);
// 按优先级升序排序(数值越小越优先)
return orders.stream()
.sorted(Comparator.comparingDouble(Order::getPriority))
.sorted(Comparator.comparingDouble(Order::getActualPriority))
.collect(Collectors.toList());
}
/**
* 递归分配优先级
* 递归分配层级化优先级路径
*/
private void assignPriorityRecursive(List<Order> orders,
List<OrderSortRule.SortCondition> conditions,
int conditionIndex,
double basePriority,
double levelRange) {
private void assignHierarchicalPriority(List<Order> orders,
List<OrderSortRule.SortCondition> conditions,
int conditionIndex,
Map<Order, List<Integer>> priorityPaths) {
// 递归终止:处理完所有条件后停止,不再添加额外序号
if (conditionIndex >= conditions.size() || CollectionUtils.isEmpty(orders)) {
return;
}
OrderSortRule.SortCondition currentCondition = conditions.get(conditionIndex);
Function<Order, ?> keyExtractor = getFieldExtractor(currentCondition.getFieldName());
String fieldName = currentCondition.getFieldName();
Function<Order, ?> keyExtractor = getFieldExtractor(fieldName);
if (keyExtractor == null) {
// 跳过无效字段,处理下一个条件
assignPriorityRecursive(orders, conditions, conditionIndex + 1, basePriority, levelRange);
log.warn("跳过无效排序字段:{}", currentCondition.getFieldName());
assignHierarchicalPriority(orders, conditions, conditionIndex + 1, priorityPaths);
return;
}
// 按当前条件分组
// 1. 按当前条件分组
Map<Object, List<Order>> groups = orders.stream()
.collect(Collectors.groupingBy(keyExtractor));
// 对分组键排序
// 2. 对分组键排序(关键:按条件配置的方向排序)
List<Object> sortedKeys = getSortedKeys(groups, currentCondition);
double groupIncrement = levelRange / groups.size();
for (int i = 0; i < sortedKeys.size(); i++) {
List<Order> group = groups.get(sortedKeys.get(i));
double groupPriority = basePriority + i * groupIncrement;
if (conditionIndex == conditions.size() - 1) {
// 最后一级条件,直接分配优先级
assignPriorityToGroup(group, groupPriority, groupIncrement);
} else {
// 递归处理下一级
assignPriorityRecursive(group, conditions, conditionIndex + 1,
groupPriority, groupIncrement);
}
// 3. 为每个分组分配层级序号(从1开始)
for (int groupIndex = 0; groupIndex < sortedKeys.size(); groupIndex++) {
Object key = sortedKeys.get(groupIndex);
List<Order> groupOrders = groups.get(key);
// 分配当前层级序号(1、2、3...)
int levelNumber = groupIndex + 1;
groupOrders.forEach(order -> priorityPaths.get(order).add(levelNumber));
// 递归处理下一级条件
assignHierarchicalPriority(groupOrders, conditions, conditionIndex + 1, priorityPaths);
}
}
/**
* 为组内订单分配优先级
* 路径转数值:严格匹配条件数格式
* 3个条件 → [1,1,1] → 1.11
* 4个条件 → [1,1,1,1] → 1.111
*/
private void assignPriorityToGroup(List<Order> orders, double basePriority, double range) {
if (CollectionUtils.isEmpty(orders)) {
return;
}
private void convertPriorityPathsToNumeric(List<Order> orders, Map<Order, List<Integer>> priorityPaths) {
for (Order order : orders) {
List<Integer> path = priorityPaths.get(order);
if (CollectionUtils.isEmpty(path)) {
order.setActualPriority(0.0);
continue;
}
double increment = range / orders.size();
for (int i = 0; i < orders.size(); i++) {
Order order = orders.get(i);
double priority = basePriority + i * increment;
order.setActualPriority(priority);
try {
// 第一部分作为整数
StringBuilder sb = new StringBuilder();
sb.append(path.get(0));
// 后续部分作为小数(严格按照路径长度)
if (path.size() > 1) {
sb.append(".");
for (int i = 1; i < path.size(); i++) {
sb.append(path.get(i));
}
}
// 转换为double
order.setActualPriority(Double.parseDouble(sb.toString()));
} catch (NumberFormatException e) {
log.error("优先级格式转换失败:{} → {}", path, e.getMessage());
order.setActualPriority(0.0);
}
}
}
......@@ -204,94 +221,114 @@ public class OrderSortService {
private Comparator<Order> createConditionComparator(OrderSortRule.SortCondition condition) {
Objects.requireNonNull(condition, "Sort condition must not be null");
Function<Order, ?> keyExtractor = getFieldExtractor(condition.getFieldName());
String fieldName = condition.getFieldName();
// 不再替换为dueDateOnly,直接使用原字段名
Function<Order, ?> keyExtractor = getFieldExtractor(fieldName);
if (keyExtractor == null) {
log.warn("No field extractor found for field: {}, using default id comparator",
condition.getFieldName());
log.warn("无字段提取器:{},使用ID排序", condition.getFieldName());
return Comparator.comparing(Order::getId);
}
Comparator<Object> fieldComparator = getFieldComparator(condition);
Comparator<Order> comparator = (Comparator<Order>) Comparator.comparing(keyExtractor, fieldComparator);
return condition.isReverse() ? comparator.reversed() : comparator;
}
/**
* 获取字段提取器
*/
private Function<Order, ?> getFieldExtractor(String fieldName) {
if (fieldName == null) {
return null;
}
return FIELD_EXTRACTORS.get(fieldName.toLowerCase());
Comparator<Object> fieldComparator = getFieldComparator(condition, fieldName);
return (Comparator<Order>) Comparator.comparing(keyExtractor, fieldComparator);
}
/**
* 获取字段比较器
* 获取字段比较器(支持reverse参数)
*/
@SuppressWarnings("unchecked")
private Comparator<Object> getFieldComparator(OrderSortRule.SortCondition condition) {
private Comparator<Object> getFieldComparator(OrderSortRule.SortCondition condition, String actualFieldName) {
Objects.requireNonNull(condition, "Sort condition must not be null");
// 尝试使用自定义比较器
// 自定义比较器优先
if (condition.getCustomComparator() != null && !condition.getCustomComparator().isEmpty()) {
try {
Class<?> clazz = Class.forName(condition.getCustomComparator());
Method method = clazz.getMethod("getInstance");
return (Comparator<Object>) method.invoke(null);
} catch (ClassNotFoundException e) {
log.error("Custom comparator class not found: {}", condition.getCustomComparator(), e);
} catch (NoSuchMethodException e) {
log.error("Custom comparator class {} must have static getInstance() method",
condition.getCustomComparator(), e);
} catch (Exception e) {
log.error("Failed to instantiate custom comparator: {}", condition.getCustomComparator(), e);
log.error("自定义比较器加载失败:{}", condition.getCustomComparator(), e);
}
}
// 根据字段类型返回默认比较器
Function<Order, ?> extractor = getFieldExtractor(condition.getFieldName());
// 按字段类型返回比较器
Function<Order, ?> extractor = getFieldExtractor(actualFieldName);
if (extractor == null) {
return Comparator.comparing(Object::toString);
Comparator<Object> defaultComparator = Comparator.comparing(Object::toString);
return condition.isReverse() ? defaultComparator.reversed() : defaultComparator;
}
// 使用示例订单获取类型信息(如果有订单)
try {
// 尝试创建示例对象或使用更安全的类型推断
Order sample = new Order();
Object sampleValue = extractor.apply(sample);
if (sampleValue instanceof Integer) {
return (Comparator<Object>) Comparator.comparingInt(o -> (Integer) o);
} else if (sampleValue instanceof Long) {
return (Comparator<Object>) Comparator.comparingLong(o -> (Long) o);
} else if (sampleValue instanceof Double) {
return (Comparator<Object>) Comparator.comparingDouble(o -> (Double) o);
} else if (sampleValue instanceof OffsetDateTime) {
return (Comparator<Object>) Comparator.comparing(o -> (OffsetDateTime) o);
} else if (sampleValue instanceof Boolean) {
return (Comparator<Object>) Comparator.comparing(o -> (Boolean) o);
// 布尔类型排序(支持reverse参数)
if (sampleValue instanceof Boolean) {
Comparator<Object> booleanComparator = (Comparator<Object>) (o1, o2) -> {
boolean b1 = (Boolean) o1;
boolean b2 = (Boolean) o2;
return Boolean.compare(b1, b2);
};
return condition.isReverse() ? booleanComparator.reversed() : booleanComparator;
}
// 日期类型:按时间排序
else if (sampleValue instanceof LocalDate) {
Comparator<Object> dateComparator = (Comparator<Object>) Comparator.comparing(o -> (LocalDate) o);
return condition.isReverse() ? dateComparator.reversed() : dateComparator;
}
// 整数类型
else if (sampleValue instanceof Integer) {
Comparator<Object> intComparator = (Comparator<Object>) Comparator.comparingInt(o -> (Integer) o);
return condition.isReverse() ? intComparator.reversed() : intComparator;
}
// 长整型
else if (sampleValue instanceof Long) {
Comparator<Object> longComparator = (Comparator<Object>) Comparator.comparingLong(o -> (Long) o);
return condition.isReverse() ? longComparator.reversed() : longComparator;
}
// 日期时间类型
else if (sampleValue instanceof OffsetDateTime) {
Comparator<Object> dateTimeComparator = (Comparator<Object>) Comparator.comparing(o -> (OffsetDateTime) o);
return condition.isReverse() ? dateTimeComparator.reversed() : dateTimeComparator;
}
} catch (Exception e) {
log.debug("Failed to determine field type for comparator, using default string comparator", e);
log.debug("字段类型推断失败:{}", actualFieldName, e);
}
return Comparator.comparing(Object::toString);
// 默认比较器
Comparator<Object> defaultComparator = Comparator.comparing(Object::toString);
return condition.isReverse() ? defaultComparator.reversed() : defaultComparator;
}
/**
* 获取排序后的分组键
*/
private List<Object> getSortedKeys(Map<Object, List<Order>> groups,
OrderSortRule.SortCondition condition) {
OrderSortRule.SortCondition condition) {
Objects.requireNonNull(groups, "Groups map must not be null");
Objects.requireNonNull(condition, "Sort condition must not be null");
Comparator<Object> comparator = getFieldComparator(condition);
String fieldName = condition.getFieldName();
Comparator<Object> comparator = getFieldComparator(condition, fieldName);
return groups.keySet().stream()
.sorted(condition.isReverse() ? comparator.reversed() : comparator)
.sorted(comparator)
.collect(Collectors.toList());
}
/**
* 获取字段提取器
*/
private Function<Order, ?> getFieldExtractor(String fieldName) {
return fieldName == null ? null : FIELD_EXTRACTORS.get(fieldName.toLowerCase());
}
/**
* 获取格式化的优先级字符串
*/
public String getFormattedPriority(double actualPriority) {
return String.valueOf(actualPriority);
}
}
\ No newline at end of file
......@@ -9,14 +9,11 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
* 订单排序服务测试类
*/
......@@ -46,6 +43,11 @@ class OrderSortServiceTest {
// 执行测试
orderSortService.assignPriority(testOrders, rule);
// 按照优先级排序
testOrders.sort(
Comparator.comparing(Order::getActualPriority).reversed()
);
// 验证多级优先级分配
printOrderPriorities(testOrders); // 调试输出
......@@ -61,12 +63,12 @@ class OrderSortServiceTest {
List<Order> orders = new ArrayList<>();
// 创建5个测试订单,具有不同的属性
for (int i = 1; i <= 5; i++) {
for (int i = 1; i <=15; i++) {
Order order = new Order();
order.setId(i);
order.setProductId(100 + i);
order.setQuantity(50.0 * i);
order.setPriority(6 - i); // 优先级:5,4,3,2,1(倒序)
order.setPriority(15 - i); // 优先级:5,4,3,2,1(倒序)
order.setDueDate(OffsetDateTime.now().plusDays(i)); // 到期日递增
order.setTardiness(i * 0.5);
order.setCanSplit(i % 2 == 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment