Scala中修改Array或List等数据结构无效果?求解释该行为
问题原因分析
你的代码里nums.drop(accumValue)操作无效果,且调试时看不到执行,核心原因如下:
- Scala集合的不可变操作特性:
drop是Scala集合的标准方法,它不会修改调用它的原数组,而是返回一个新的数组实例——这个新数组是原数组去掉前accumValue个元素后的结果。但你代码里只是调用了nums.drop(accumValue),却没有把返回的新数组赋值给任何变量,所以这个操作的结果直接被丢弃,原nums数组完全不受影响。 - JIT编译优化导致代码被跳过:因为这行代码的结果没有被使用,JVM的即时编译器(JIT)会把它判定为“无用代码”,直接优化掉不执行,所以你调试时看不到这行的执行痕迹。
另外你的整个逻辑还有两处关键问题:
foldLeft的返回值是最后一次计算的accumValue,但你根本没用到这个返回值,最后直接返回nums.toList,所以整个foldLeft块里的所有操作对最终结果都没有任何影响。- 判断重复的逻辑
nums.tail.contains(nextEl)错误:比如数组第一个元素如果在后面出现,nums.tail是从第二个元素开始的集合,会检测到包含,但如果是中间元素重复,这个逻辑也会出错;而且每次调用contains都会遍历整个数组尾部,效率极低。
正确实现找重复元素的方式
如果你想找出数组中所有重复出现的元素,可以用更简洁高效的方式:
方式1:按元素分组(不保持顺序)
def findDuplicates(nums: Array[Int]): List[Int] = { nums.groupBy(identity) // 按元素值分组 .filter { case (_, group) => group.length > 1 } // 过滤出出现次数>1的组 .keys.toList // 提取重复的元素值 }
方式2:保持元素第一次重复出现的顺序
def findDuplicates(nums: Array[Int]): List[Int] = { nums.foldLeft((Set.empty[Int], List.empty[Int])) { case ((seen, duplicates), num) => if (seen.contains(num)) { // 如果元素已见过,加入重复列表 (seen, num :: duplicates) } else { // 如果没见过,加入已见集合 (seen + num, duplicates) } }._2.reverse // 反转列表,保持原数组中重复元素出现的顺序 }
内容的提问来源于stack exchange,提问作者Anastasia
相关产品推荐
相关产品推荐

