在java中创建数组列表?

时间:2014-02-17 15:29:00

标签: java arrays

程序在每个特征向量(列)中获得0和1的频率并将其存储到数组中。但是当我访问我的数组列表(观察到例如observe.get(0)[0])时,它返回矩阵中的所有0。

DoubleMatrix[] featurevec = new DoubleMatrix[tempfeatures.numCols()];
for (int i = 0; i< featurevec.length; i++) {
    featurevec[i] = tempfeatures.extractVector(false,i);
}

double[]f = new double[2];
ArrayList<double[]> observed = new ArrayList<>();
for (int j = 0; j< featurevec.length; j++) 
{
    for (int i = 0; i< featurevec[j].getNumElements(); i++) 
    {
        if (featurevec[j].get(i) == 1) 
            f[0]++;
        else
            f[1]++;
    }
    observed.add(f);
}

4 个答案:

答案 0 :(得分:1)

问题是你永远不会重置f []。您总是递增相同的数组,您需要在每次传递时创建一个新数组。

ArrayList<double[]> observed = new ArrayList<>();
for (int j = 0; j< featurevec.length; j++) {
    double[] f = new double[2]; //move this here
    for (int i = 0; i< featurevec[j].getNumElements(); i++) {
        if (featurevec[j].get(i) == 0) //I recommend changing this
            f[0]++;
        else
            f[1]++;
    }
    observed.add(f);
}

另请注意,我将if (featurevec[j].get(i) == 1)更改为if (featurevec[j].get(i) == 0),因此0计数存储在f [0]中,1计数存储在f [1]中。我认为这更清楚,并且更容易管理。

这取决于DoubleMatrix是什么,不确定,因为你没有告诉我们。你可以通过做这样的事情来消除你的if / else语句,因为你知道你只有0和1:

ArrayList<int[]> observed = new ArrayList<int[]>();
for (int j = 0; j< featurevec.length; j++) {
    int[] f = new int[2];
    totalOnes = arraySum(featurevec[j]);
    //total elements - total one count = total zero count
    f[0] = featurevec[j].getNumElements() - totalOnes; 
    f[1] = totalOnes;
    observed.add(f);
}

//not sure of arr's type, unclear from your code, probably Integer?
private int arraySum(ArrayList<T> arr) { 
    int sum = 0;
    //this loop syntax might not work depending on DoubleMatrix's implementation 
    for(int i : arr) 
        sum+=i;
    return sum;
}

虽然这个解决方案仍然是O(n ^ 2),但也许它更清晰一点。

我也不确定你为什么要把f []设为double [],因为你只得到0和1的数。我也改变了。

答案 1 :(得分:0)

我已经弄明白了:我只需要像这样初始化我的列表:

    DoubleMatrix[] featurevec = new DoubleMatrix[tempfeatures.numCols()];
    for (int i = 0; i< featurevec.length; i++) {
        featurevec[i] = tempfeatures.extractVector(false,i);
    }
    double[]f = new double[2];
    ArrayList<double[]> observed = new ArrayList<>(tempfeatures.numCols());
    for (int i = 0; i< featurevec.length; i++)
    observed.add(new double[2]);

    for (int j = 0; j< featurevec.length; j++) {
        for (int i = 0; i< featurevec[j].getNumElements(); i++) {
             if (featurevec[j].get(i) == 1) {
                 observed.get(j)[0]++;
             // f[0]++;
            }
            else
                 observed.get(j)[1]++;
               //  f[1]++;
        //observed.add(f);
        }

    }

但它的性能很低。因为我有1461 * 18584行列矩阵。有人可以向我建议一个更好的方法吗?

答案 2 :(得分:0)

问题是您只创建一个数组并重复修改并再次将其添加到列表中。

你需要移动

double[]f = new double[2];

在循环中。

DoubleMatrix[] featurevec = new DoubleMatrix[tempfeatures.numCols()];
for (int i = 0; i< featurevec.length; i++) {
    featurevec[i] = tempfeatures.extractVector(false,i);
}

ArrayList<double[]> observed = new ArrayList<>();
for (int j = 0; j< featurevec.length; j++) 
{
    double[]f = new double[2];
    for (int i = 0; i< featurevec[j].getNumElements(); i++) 
    {
        if (featurevec[j].get(i) == 1) 
            f[0]++;
        else
            f[1]++;
    }
    observed.add(f);
}

答案 3 :(得分:0)

每次调用observed.add(f)时,它都会再次将相同的数组添加到观察列表中。最后,您有一个包含featurevec.length对同一数组的引用的ArrayList。你需要在循环中创建数组f,所以每次都得到一个新数组:

for (int j = 0; j < featurevec.length; j++) {
    double[] f = new double[2];
    ...
    observed.add(f);
}