Java 为什么产出不同?为什么数据可以自我改变?

Java 为什么产出不同?为什么数据可以自我改变?,java,Java,这是我的密码。我想从文件中加载数据并用代码处理它。我对我的输出感到困惑。数据本身可以改变它。这是main类中的main方法。有一个代码打印(i);这段代码输出错误 public static void main(String[] args) { ArrayList<Integer> ar = new ArrayList(); ar.add(0); ar.add(2); ar.add(4); Data ds = new Data();

这是我的密码。我想从文件中加载数据并用代码处理它。我对我的输出感到困惑。数据本身可以改变它。这是main类中的main方法。有一个代码打印(i);这段代码输出错误

public static void main(String[] args) {

    ArrayList<Integer> ar = new ArrayList();
    ar.add(0);
    ar.add(2);
    ar.add(4);

    Data ds = new Data();
    ds.loadDataSet(new Loader(), ar);
    System.out.println("in main class");
    for (int i = 0; i < ds.size(); i++) {
        ds.print(i);   //give wrong output
    }
 }
这就是loader.class。从中获取数据的类。这只是一个例子。在我的真实代码中,从csv文件加载的数据。这不是问题

public class Loader {

private String[] name;
private double[][] value;

public Loader() {
    name = new String[] {"A", "B", "C", "D", "E"};
    value = new double[][] {{1, 2, 3, 4, 5}, {4, 5, 6, 7, 8}, {7, 8, 9, 10, 11}, {10, 11, 12, 13, 14}, {13, 14, 15, 16, 17}};
}

public String getTupleName(int index) {
    return name[index];        
}

public double getValue(int indexTuple, int indexAttribute) {
    return value[indexTuple][indexAttribute];
}

public int dataSize() {
    return value.length;
}
}
这就是输出

inside data.class
A--1.0 3.0 5.0 
B--4.0 6.0 8.0 
C--7.0 9.0 11.0 
D--10.0 12.0 14.0 
E--13.0 15.0 17.0 
in main class
A--13.0 15.0 17.0 
B--13.0 15.0 17.0 
C--13.0 15.0 17.0 
D--13.0 15.0 17.0 
E--13.0 15.0 17.0 

为什么方法中打印的输出与Data.class中打印的输出主要不同?为什么数据会自行更改,它必须相同,请帮助。

tl;博士,你有一堵代码墙,诚实地说,你可以做得更好,把代码的数量减少到再现你问题的尽可能小的例子

然而,从输出中,我几乎可以99%肯定地说,您正在创建一个单行实例,处理其中的值,并多次向单行添加引用。相反,您需要为每一行创建一个新对象,并分别填充它们。这样,A、B、C、D、E行中的每一行都指向不同的行对象


可以使用以下伪代码演示您遇到的问题:

ArrayList<Foo> list = new ArrayList();
Foo aFoo = new Foo();
aFoo.Bar = 2;
list.Add(aFoo);
aFoo.Bar = 3;
list.Add(aFoo);

foreach(x in list):
    print(x);

tl;博士,你有一堵代码墙,诚实地说,你可以做得更好,把代码的数量减少到再现你问题的尽可能小的例子

然而,从输出中,我几乎可以99%肯定地说,您正在创建一个单行实例,处理其中的值,并多次向单行添加引用。相反,您需要为每一行创建一个新对象,并分别填充它们。这样,A、B、C、D、E行中的每一行都指向不同的行对象


可以使用以下伪代码演示您遇到的问题:

ArrayList<Foo> list = new ArrayList();
Foo aFoo = new Foo();
aFoo.Bar = 2;
list.Add(aFoo);
aFoo.Bar = 3;
list.Add(aFoo);

foreach(x in list):
    print(x);

double[]value
是在循环外部定义的,因此它是同一个数组,您可以在循环中覆盖它的值

快速修复:

for (int i = 0; i < setOfInstance.length; i++) {
    double[] value = new double[attributeIndex.size()];
    for (int j = 0; j < value.length; j++) {
        value[j] = loader.getValue(i, attributeIndex.get(j));
    }
    setOfInstance[i] = new Instance(loader.getTupleName(i), value);

    print(i);   //give true output
}
for(int i=0;i

还要注意,
print(i)可能应该是
print(setOfInstance[i])
在这个块中

double[]value
在循环外部定义,因此它是同一个数组,并且在循环中覆盖它的值

快速修复:

for (int i = 0; i < setOfInstance.length; i++) {
    double[] value = new double[attributeIndex.size()];
    for (int j = 0; j < value.length; j++) {
        value[j] = loader.getValue(i, attributeIndex.get(j));
    }
    setOfInstance[i] = new Instance(loader.getTupleName(i), value);

    print(i);   //give true output
}
for(int i=0;i

还要注意,
print(i)可能应该是
print(setOfInstance[i])
在这个块中

为了更快地获得更好的帮助,请发布一个。为了更快地获得更好的帮助,请发布一个。+1将代码简化到最低限度,以完成您想做的事情,可能也会显示错误。非常感谢,您的解释很有用,问题现在已经解决了+1将代码简化到最低限度来做你想做的事情很可能也会出现错误。非常感谢,你的解释很有用,问题现在已经解决了
for (int i = 0; i < setOfInstance.length; i++) {
    double[] value = new double[attributeIndex.size()];
    for (int j = 0; j < value.length; j++) {
        value[j] = loader.getValue(i, attributeIndex.get(j));
    }
    setOfInstance[i] = new Instance(loader.getTupleName(i), value);

    print(i);   //give true output
}