Java 嵌套for循环中的手动阵列复制

Java 嵌套for循环中的手动阵列复制,java,arrays,Java,Arrays,我试图找到所有2,将它们移动到数组的后面,并将它们转换为0,而不丢失数组的顺序。例如,[1,2,3,2,2,4,5]将变成[1,3,4,5,0,0]。我的代码工作正常,但IDE告诉我嵌套的for循环正在手动复制数组,并希望我将其替换为System.arraycopy()。我该怎么做呢 代码如下所示: int[] numbers = {1,2,3,2,2,4,5}; for (int i = 0; i < numbers.length; i++){ if (n

我试图找到所有2,将它们移动到数组的后面,并将它们转换为0,而不丢失数组的顺序。例如,[1,2,3,2,2,4,5]将变成[1,3,4,5,0,0]。我的代码工作正常,但IDE告诉我嵌套的for循环正在手动复制数组,并希望我将其替换为
System.arraycopy()
。我该怎么做呢

代码如下所示:

    int[] numbers = {1,2,3,2,2,4,5};
    for (int i = 0; i < numbers.length; i++){
        if (numbers[i] == 2){
            for (int j = i; j < numbers.length - 1; j++){
                numbers[j] = numbers[j + 1];
            }
            numbers[numbers.length-1] = 0;
            i --;
        }
    }
List<Integer> notTwos = new ArrayList<>();
int numberOfTwos = 0;
for (int i=0; i<source.length; i++) {
  if (source[i] == 2) {
    numberOfTwos++;
  } else {
    notTwo.append(source[i]);
  }
}
... simply append `numberOfTwo` 0s to the list, and then turn it into an array
int[]数字={1,2,3,2,2,4,5};
for(int i=0;i
使用System.arrayCopy替换内部循环后,代码应如下所示:

    int[] numbers = { 1, 2, 3, 2, 2, 4, 5 };
    for (int i = 0; i < numbers.length; i++) {
        if (numbers[i] == 2) {
            System.arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i);
            numbers[numbers.length - 1] = 0;
            i--;
        }
    }
int[]数字={1,2,3,2,2,4,5};
for(int i=0;i
内部循环可以用
阵列副本替换,但是,您不需要内部循环:

int[] numbers = {1,2,3,2,2,4,5};
int j = 0;
for (int i = 0; i < numbers.length; i++){
    if (numbers[i] != 2){
        numbers[j++] = numbers[i];
    }
}
while (j < numbers.length) {
   numbers[j++] = 0;
}

关键的事情很简单:如果你可以减少你负责的代码行(例如通过使用实用方法,如
Arrays.arraycopy()
),那么就这样做

记住:你今天写的每一行,你必须明天阅读和理解,并且可能在5周或几个月后修改

但是:我认为你把这里的事情复杂化了。我会使用一个临时列表,如下所示:

    int[] numbers = {1,2,3,2,2,4,5};
    for (int i = 0; i < numbers.length; i++){
        if (numbers[i] == 2){
            for (int j = i; j < numbers.length - 1; j++){
                numbers[j] = numbers[j + 1];
            }
            numbers[numbers.length-1] = 0;
            i --;
        }
    }
List<Integer> notTwos = new ArrayList<>();
int numberOfTwos = 0;
for (int i=0; i<source.length; i++) {
  if (source[i] == 2) {
    numberOfTwos++;
  } else {
    notTwo.append(source[i]);
  }
}
... simply append `numberOfTwo` 0s to the list, and then turn it into an array
List notTwos=new ArrayList();
int numberOfTwos=0;

对于(int i=0;i以下语句:

for (int j = i; j < numbers.length - 1; j++){
    numbers[j] = numbers[j + 1];
}
像IntelliJ这样的IDE应该建议当您按下
alt
+
enter
(默认组合键)时自动执行此操作


现在大约 从文档中,将n个元素(最后一个参数)从源数组(第一个参数)复制到目标数组(第三个参数),并从相应的索引(第二个和第四个参数)开始

更具体地说,当调用
arraycopy(numbers,i+1,numbers,i,numbers.length-1-i)
时,参数是:

  • 数字
    :源数组
  • i+1
    :源数组中的起始位置
  • 数字
    :目标阵列
  • i
    :目标数据中的起始位置
  • numbers.length-1-i
    :要复制的数组元素数
  • 在您的情况下,元素将从数组复制到自身,但源起始位置从目标起始位置移动的事实将导致您所追求的全局移动(将元素向左移动)


    关于要移动的元素数,它应该移动
    i
    元素减去第一个不移动且只被覆盖的元素。因此
    length-1-i

    如果IDE建议,可能有自动替换代码的功能。如果是IntelliJ,您是否尝试过
    alt
    +
    enter
    ?但您的代码不仅仅是按原样复制数组……在我看来,这是这里发布的实现中最好的一个,因为这个实现有一个O(N)运行时(与问题中的O(N2)相比)和O(1)空间开销。一个小小的修改可以是将末尾的while循环替换为:Arrays.fill(numbers,j,numbers.length,0)AOLKE公平,你也应该考虑看看其他答案关于优化你的代码后,你已经理解了这一解释。