简体   繁体   English

在 static 方法中复制数组 Java 时的奇怪行为

[英]Strange behavior when copying an array Java in static method

I have a problem with creating a copy of an array in Java.我在 Java 中创建数组副本时遇到问题。

I pass a copy of the received data to my custom sort method.我将收到的数据的副本传递给我的自定义排序方法。 The problem is the original array changes too.问题是原始数组也发生了变化。 I 've tried with .clone() and with some other methods which I found on the internet but the result always was the same: sorted array.我已经尝试过使用.clone()以及我在互联网上找到的其他一些方法,但结果总是相同的:排序数组。 I think it's specific for java behaviour and it's super easy to fix.我认为它特定于 java 行为,并且非常容易修复。 Probably something with static keyword (?).可能与 static 关键字(?)有关。 Normally I'm programming in JS, Java is not for me:(通常我在 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]);
        }
    }

How to create a true copy of the received data in mySort method?如何在 mySort 方法中创建接收数据的真实副本?

All code:所有代码:

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 +
                '}';
    }
}

The issue is that you are sorting by swapping the content of the Example instances.问题是您通过交换Example实例的内容进行排序。 Imagine those instances with the corresponding values (just in an abstract way):想象那些具有相应值的实例(只是以抽象的方式):

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

You are swapping the values , not the positions of the instances.您正在交换values ,而不是实例的位置

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

You can see that the values are sorted, but this hasn't affected the position of instances.您可以看到已排序,但这并未影响实例的 position。 Every array that references those instances will obviously see those changes as the values are changed, not the position in the sort array.引用这些实例的每个数组显然会在更改时看到这些更改,而不是排序数组中的position

What you need is:你需要的是:

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

As you can see, the order itself is changed, not whatever an instance contains.如您所见,订单本身已更改,而不是实例包含的任何内容。 This will obviously only be visible in the one array, the one you swap the instances in.这显然只会在一个数组中可见,即您交换实例的那个数组。

Your sorting function has to be like so:您的排序 function 必须像这样:

    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;
    }

Again, your current version swaps values not positions .同样,您当前的版本交换而不是位置 I hope that's clear now.我希望现在很清楚。


Here's the whole thing:这是整个事情:

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 +
                '}';
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM