TreeSet<String> 默认使用字符串的 字典序排序,它不会识别 "电芯10" 中的 10 是一个数字,而是当成字符 '1' 和 '0' 来处理。
解决方案:自定义 Comparator 实现“自然排序”或“数值感知排序”
我们需要让 TreeSet 按照“电芯”后面的数字进行 数值排序,而不是字符串排序。
方法一:使用自定义 Comparator(推荐)
import java.util.*;
Set<String> cellKeys = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
// 提取 "电芯" 后面的数字部分
Integer num1 = extractNumber(o1, "电芯");
Integer num2 = extractNumber(o2, "电芯");
if (num1 != null && num2 != null) {
return num1.compareTo(num2); // 数值比较
}
// 如果无法提取数字,fallback 到字典序
return o1.compareTo(o2);
}
private Integer extractNumber(String s, String prefix) {
int start = s.indexOf(prefix);
if (start == -1) return null;
start += prefix.length();
StringBuilder sb = new StringBuilder();
while (start < s.length() && Character.isDigit(s.charAt(start))) {
sb.append(s.charAt(start++));
}
return sb.length() > 0 ? Integer.parseInt(sb.toString()) : null;
}
});
String unit = "";
for (Map<String, Double> cellData : timeToCellData.values()) {
cellKeys.addAll(cellData.keySet());
}
排序结果将是:
"堆1-1簇_PACK1_电芯1(V)"
"堆1-1簇_PACK1_电芯2(V)"
"堆1-1簇_PACK1_电芯10(V)"
"堆1-1簇_PACK1_电芯11(V)"
方法二:Java 8+ 更优雅的写法(使用 Comparator.comparing)
Set<String> cellKeys = new TreeSet<>((o1, o2) -> {
Integer n1 = extractNumber(o1, "电芯");
Integer n2 = extractNumber(o2, "电芯");
if (n1 != null && n2 != null) {
return n1 - n2; // 简单数值差(注意:避免大数溢出)
}
return o1.compareTo(o2);
});
331

被折叠的 条评论
为什么被折叠?



