
本文介绍如何将形如“1 456 2 100 3 600 1 400”的空格分隔字符串,按每对中的**分数值(而非id)升序重排**,并保持id与分数的绑定关系,最终输出格式一致的排序后字符串。
在处理这类“交替键值对”字符串时,直接按字符串或数字ID排序会导致逻辑错误(例如ID为1的两条记录被拆散或误排),关键在于语义建模:将每两个连续元素视为一个逻辑单元——即 id 和 score 组成的实体。因此,推荐采用面向对象方式封装数据,再借助Java集合的排序能力实现精准控制。
首先定义一个轻量级数据类:
public class Person {
private final String id;
private final int score;
public Person(String id, int score) {
this.id = id;
this.score = score;
}
// 重写 toString() 以支持 "id score" 格式输出
@Override
public String toString() {
return id + " " + score;
}
}接着解析原始字符串,按步长为2切分,并构建 Person 对象列表:
String input = "1 456 2 100 3 600 1 400";
String[] parts = input.split("\\s+"); // 使用正则处理多个空格更健壮
List people = new ArrayList<>();
for (int i = 0; i < parts.length; i += 2) {
if (i + 1 >= parts.length) {
throw new IllegalArgumentException("Invalid input: odd number of tokens");
}
String id = parts[i];
int score = Integer.parseInt(parts[i + 1]);
people.add(new Person(id, score));
} 然后使用 List.sort() 配合自定义比较器,按 score 升序排列(若需降序,可改为 Integer.compare(p2.score, p1.score)):
people.sort(Comparator.comparingInt(p -> p.score));
最后,将排序后的对象流式转换为字符串,用单个空格连接(注意:原题示例输出无逗号,因此应使用 " " 而非 ","):
String result = people.stream()
.map(Person::toString)
.collect(Collectors.joining(" "));
System.out.println(result); // 输出:2 100 1 400 1 456 3 600✅ 注意事项:
- 不要使用 HashMap 存储,因ID可能重复(如本例中ID=1出现两次),会导致数据丢失;
- 解析时务必校验数组长度为偶数,避免 ArrayIndexOutOfBoundsException;
- 若输入含前导/尾随空格或多空格,split("\\s+") 比 split(" ") 更安全;
- 如需稳定排序(相同分数时保持原始顺序),可改用 Collections.stableSort(...) 或在比较器中添加次级条件(如索引)。
该方案结构清晰、类型安全、易于扩展(例如后续增加姓名、时间戳等字段),是处理此类结构化字符串排序问题的标准实践。










