You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Dart列表排序异常:长度34且compare返回0时元素位置错乱

为什么Dart中用返回0的compare函数排序列表会出现元素位置错乱?

当对长度为34的int列表使用始终返回0的compare函数排序时,出现了元素位置错乱的情况,代码及结果如下:

问题代码

final nums = List.generate(34, (i) => i);
final sortedNums = nums.sorted((a, b) => 0);

print('nums: $nums');
print('sortedNums: $sortedNums');

执行结果

nums: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]
sortedNums: [11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 33, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 21]

原因分析

Dart中List.sorted(通常来自package:collection)使用的是不稳定排序算法。不稳定排序的核心特点是:当两个元素被compare函数判定为相等(返回0)时,不会保证它们在排序后的列表中保持原始的相对顺序。

不同长度的列表会触发排序算法的不同分支逻辑,34这个长度刚好触发了算法中的交换操作,导致部分原本有序的元素位置被打乱。

解决方案

如果需要在元素相等时保留原始顺序(即实现稳定排序),可以绑定元素的原始索引,在compare函数中显式比较索引来维持顺序:

final nums = List.generate(34, (i) => i);
// 绑定原始索引,相等时通过比较索引确保顺序不变
final sortedNums = nums.asMap().entries
    .sorted((entryA, entryB) {
      if (entryA.value == entryB.value) {
        return entryA.key.compareTo(entryB.key);
      }
      return 0;
    })
    .map((entry) => entry.value)
    .toList();

print('nums: $nums');
print('sortedNums: $sortedNums'); // 输出与原列表完全一致

总结

当compare函数返回0时,不要默认认为元素会保持原始位置——不稳定排序算法会根据自身逻辑调整相等元素的位置。如果需要稳定排序,必须显式处理索引比较,或使用稳定排序的实现。

内容的提问来源于stack exchange,提问作者sm-sayedi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 06:45:05