java - 以静态方法复制数组Java时的奇怪行为
问题描述
我在用 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
想象那些具有相应值的实例(只是以抽象的方式):
e1 = 3;
e2 = 1;
e3 = 2;
您正在交换values,而不是实例的位置。
e1 = 1;
e2 = 2;
e3 = 3;
您可以看到值已排序,但这并没有影响实例的位置。引用这些实例的每个数组显然会在值更改时看到这些更改,而不是排序数组中的位置。
你需要的是:
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;
}
同样,您当前的版本交换值而不是位置。我希望现在很清楚。
这是整个事情:
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 +
'}';
}
}
推荐阅读
- webpack - 在单独的文件中生成 CSS 浏览器前缀
- python - 使用带有参数的 python 调用 API
- multithreading - 为什么析构函数挂起?
- r - 在 xtable 中设置不同的数字
- amazon-web-services - 监控 ec2 实例的 Linux 日志
- sql - 如何在单行中获取多个列值?
- html - bootstrap 4 导航栏折叠不起作用(使用 JQuery - popper - bootstrap
- flutter - 在flutter_bloc中为(注销)功能添加单独的块
- python - 使用 BeautifulSoup 获取图像 url,其中 src= data:image/gif;base64,
- python - 我想将自定义 Django 视图转换为 Django-Rest_framework Endpoint