【问题标题】:Strange behavior when copying an array Java in static method以静态方法复制数组Java时的奇怪行为
【发布时间】:2020-06-01 08:21:17
【问题描述】:

我在用 Java 创建数组副本时遇到问题。

我将收到的数据的副本传递给我的自定义排序方法。 问题是原始数组也发生了变化。我试过.clone() 和我在互联网上找到的其他一些方法,但结果总是一样的:排序数组。我认为它特定于 java 行为,并且非常容易修复。可能带有静态关键字(?)的东西。通常我用 JS 编程,Java 不适合我:(

    public static void mySort(Example[] data) {
        Example[] copy = Arrays.copyOf(data, data.length);
        Example[] sortedArray= customSort(copy);
        System.out.println("Original data (should not be sorted): ");
        for (int i = 0; i < data.length; i++) {
            System.out.println(data[i]);
        }
    }

如何在 mySort 方法中创建接收到的数据的真实副本?

所有代码:

package com.company;

import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;

public class Main {

    public static void main(String[] args) {

        Example examples[] = new Example[20];

        for (int i = 0; i < examples.length; i++) {
            int randomValue1 = ThreadLocalRandom.current().nextInt(1, 6);
            double randomValue2 = ThreadLocalRandom.current().nextDouble();
            examples[i] = new Example(randomValue1, randomValue2);
        }

        System.out.println("Beforesort: ");
        for (int i = 0; i < examples.length; i++) {
            System.out.println(i + ". " + examples[i]);
        }

        mySort(examples);
    }

    public static void mySort(Example[] data) {
        Example[] copy = Arrays.copyOf(data, data.length);
        Example[] sortedArray= customSort(copy);
        System.out.println("Original data (should not be sorted): ");
        for (int i = 0; i < data.length; i++) {
            System.out.println(data[i]);
        }
    }

// you can ignore this, it's just customSort
    static Example[] customSort(Example[] copy) {

        for (int i = 0; i < copy.length; i++) {
            for (int j = 0; j < copy.length - i - 1; j++)
                if (copy[j].value1 != copy[j + 1].value1) {
                    if (copy[j].value1 > copy[j + 1].value1) {
                        int temp = copy[j].value1;
                        copy[j].value1 = copy[j + 1].value1;
                        copy[j + 1].value1 = temp;
                    }
                } else {
                    if (copy[j].value2 > copy[j + 1].value2) {
                        double temp = copy[j].value2;
                        copy[j].value2 = copy[j + 1].value2;
                        copy[j + 1].value2 = temp;
                    }
                }


        }
        return copy;
    }

}

class Example {
    int value1;
    double value2;

    public Example(int value1, double value2) {
        this.value1 = value1;
        this.value2 = value2;
    }

    @Override
    public String toString() {
        return "Example{" +
                "value1=" + value1 +
                ", value2=" + value2 +
                '}';
    }
}

【问题讨论】:

  • 看起来您实际上并没有将传递数组中Example 对象的顺序排序为customSort,而是通过更改Example 对象的值来“排序”。你知道吗?你想要吗?
  • @akuzminykh 我想将data 的副本传递给customSort 方法。不应更改原始数组 (data)。
  • 我知道,但这正是您正在做的事情。您通过在 Example 实例之间交换 value1 字段的值来进行排序。这会影响实例本身,而不是传递数组中实例的位置。你明白问题了吗?你不是在改变元素的位置,而是在改变它们的内容。如果还不清楚,我可能需要写一个答案。
  • 我懂一点。但我不知道该怎么做。如果您写下答案,我将非常感激

标签: java arrays copy


【解决方案1】:

问题是您通过交换Example 实例的内容 进行排序。想象那些具有相应值的实例(只是以抽象的方式):

e1 = 3;
e2 = 1;
e3 = 2;

您正在交换,而不是实例的位置

e1 = 1;
e2 = 2;
e3 = 3;

您可以看到 已排序,但这并没有影响实例的位置。引用这些实例的每个数组显然会在 values 更改时看到这些更改,而不是排序数组中的 position

你需要的是:

e2 = 1;
e3 = 2;
e1 = 3;

如您所见,订单本身已更改,而不是实例包含的任何内容。这显然只会在一个数组中可见,即您交换实例的那个数组。

你的排序功能必须是这样的:

    static Example[] customSort(Example[] copy) {

        for (int i = 0; i < copy.length; i++) {
            for (int j = 0; j < copy.length - i - 1; j++)
                if (copy[j].value1 != copy[j + 1].value1) {
                    if (copy[j].value1 > copy[j + 1].value1) {
                        Example temp = copy[j];
                        copy[j] = copy[j + 1];
                        copy[j + 1] = temp;
                    }
                } else {
                    if (copy[j].value2 > copy[j + 1].value2) {
                        Example temp = copy[j];
                        copy[j] = copy[j + 1];
                        copy[j + 1] = temp;
                    }
                }


        }
        return copy;
    }

同样,您当前的版本交换的是 values 而不是 positions。我希望现在已经清楚了。


这就是全部内容:

import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;

public class Main {

    public static void main(String[] args) {

        Example examples[] = new Example[20];

        for (int i = 0; i < examples.length; i++) {
            int randomValue1 = ThreadLocalRandom.current().nextInt(1, 6);
            double randomValue2 = ThreadLocalRandom.current().nextDouble();
            examples[i] = new Example(randomValue1, randomValue2);
        }

        System.out.println("Beforesort: ");
        for (int i = 0; i < examples.length; i++) {
            System.out.println(i + ". " + examples[i]);
        }

        mySort(examples);
    }

    public static void mySort(Example[] data) {
        Example[] copy = Arrays.copyOf(data, data.length);
        Example[] sortedArray= customSort(copy);
        System.out.println("Original data (should not be sorted): ");
        for (int i = 0; i < data.length; i++) {
            System.out.println(i + ". " + data[i]);
        }

        System.out.println("Sorted data: ");
        for (int i = 0; i < sortedArray.length; i++) {
            System.out.println(i + ". " + sortedArray[i]);
        }
    }

// you can ignore this, it's just customSort
    static Example[] customSort(Example[] copy) {

        for (int i = 0; i < copy.length; i++) {
            for (int j = 0; j < copy.length - i - 1; j++)
                if (copy[j].value1 != copy[j + 1].value1) {
                    if (copy[j].value1 > copy[j + 1].value1) {
                        Example temp = copy[j];
                        copy[j] = copy[j + 1];
                        copy[j + 1] = temp;
                    }
                } else {
                    if (copy[j].value2 > copy[j + 1].value2) {
                        Example temp = copy[j];
                        copy[j] = copy[j + 1];
                        copy[j + 1] = temp;
                    }
                }


        }
        return copy;
    }

}

class Example {
    int value1;
    double value2;

    public Example(int value1, double value2) {
        this.value1 = value1;
        this.value2 = value2;
    }

    @Override
    public String toString() {
        return "Example{" +
                "value1=" + value1 +
                ", value2=" + value2 +
                '}';
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 2016-10-27
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    相关资源
    最近更新 更多