如何用System.arraycopy()替代嵌套循环实现数组指定元素调整
优化数组操作:用
System.arraycopy()替代嵌套循环实现需求 嘿,我来帮你搞定这个代码优化的问题!你的需求是把数组里所有的2移到末尾并转换成0,同时保持其余元素的原有顺序,原代码逻辑是正确的,但嵌套循环手动复制元素的写法确实可以用System.arraycopy()来优化——不仅代码更简洁,效率也会更高,毕竟这是JVM原生支持的native方法,底层实现比手动循环高效得多。
先看原代码的问题
原代码里每次遇到值为2的元素,就用内层循环把后面的元素逐个往前挪一位,这种手动遍历复制的方式不仅代码繁琐,而且在数组规模较大时,性能会明显不如批量复制的System.arraycopy()。
用System.arraycopy()优化后的代码
我们可以直接用System.arraycopy()批量移动元素,替代内层的手动循环,同时用一个计数器跟踪已经处理过的2的数量,避免重复操作末尾的0:
int[] numbers = {1,2,3,2,2,4,5}; int countOfTwos = 0; for (int i = 0; i < numbers.length - countOfTwos; i++) { if (numbers[i] == 2) { // 批量移动:把i+1到末尾的元素往前挪一位 System.arraycopy(numbers, i + 1, numbers, i, numbers.length - i - 1); // 将对应位置设为0(不是每次都设最后一位,避免覆盖已处理的0) numbers[numbers.length - 1 - countOfTwos] = 0; countOfTwos++; i--; // 当前位置被新元素覆盖,需要重新检查 } }
代码解释:
System.arraycopy()的参数依次是:源数组、源起始索引、目标数组、目标起始索引、要复制的元素个数。这里就是把从i+1开始的numbers.length - i -1个元素,批量复制到从i开始的位置,一次性完成原内层循环的工作。countOfTwos用来统计已经处理过的2的数量,这样我们可以把0放到正确的末尾位置,同时让循环提前结束(后面countOfTwos个位置已经是0,无需再检查)。
更高效的进阶思路
如果不需要严格贴合原代码“遇到2就立即移动”的执行过程,还有一种更简洁高效的写法:先把所有非2的元素移到数组前面,再把剩下的位置统一填充为0,全程没有嵌套循环,也不需要i--这种容易出错的操作:
int[] numbers = {1,2,3,2,2,4,5}; int index = 0; // 第一步:收集所有非2元素,放到数组前半部分 for (int num : numbers) { if (num != 2) { numbers[index++] = num; } } // 第二步:把剩余位置全部设为0 while (index < numbers.length) { numbers[index++] = 0; }
这种方式只需要两次线性遍历,时间复杂度是O(n),比原代码的O(n²)(最坏情况全是2)效率提升非常明显,代码也更易读维护。
内容的提问来源于stack exchange,提问作者Brodie Terrence
相关产品推荐
相关产品推荐

