优先级计算

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