Java 多维ArrayList上的迭代

Java 多维ArrayList上的迭代,java,arraylist,iteration,Java,Arraylist,Iteration,我找了很多问题的答案,但到目前为止什么也没找到 我正在为矩阵上的一些运算实现一个类。起初我使用了2x2数组,它们很有效,但现在对于其他一些方法,我决定切换到更通用的2x2 ArrayList 我曾经在这个网站上发现了一个类,用于将元素添加到此类列表(),为了方便起见,我添加了一些新方法: import java.util.ArrayList; public class TwoDimensionalArrayList<T> extends ArrayList<ArrayList

我找了很多问题的答案,但到目前为止什么也没找到

我正在为矩阵上的一些运算实现一个类。起初我使用了2x2数组,它们很有效,但现在对于其他一些方法,我决定切换到更通用的2x2 ArrayList

我曾经在这个网站上发现了一个类,用于将元素添加到此类列表(),为了方便起见,我添加了一些新方法:

import java.util.ArrayList;

public class TwoDimensionalArrayList<T> extends ArrayList<ArrayList<T>>
{
    private static final long serialVersionUID = 1L;

    public void addToInnerArray(int index, T element)
    {
        while (index >= this.size())
        {
            this.add(new ArrayList<T>());
        }
        this.get(index).add(element);
    }

    public void addToInnerArray(int index, int index2, T element)
    {
        while (index >= this.size())
        {
            this.add(new ArrayList<T>());
        }

        ArrayList<T> inner = this.get(index);
        while (index2 >= inner.size())
        {
            inner.add(null);
        }

        inner.set(index2, element);
    }

    public T getFromInnerArray(int index, int index2)
    {
        ArrayList<T> inner = this.get(index);
        return inner.get(index2);
    }

    public void removeFromInnerArray(int index, int index2)
    {
        ArrayList<T> inner = this.get(index);
        inner.remove(index2);
        this.remove(index);
        this.add(index, inner);
    }

    public void setToInnerArray(int index, int index2, T t)
    {
        this.removeFromInnerArray(index, index2);
        this.addToInnerArray(index, index2, t);
    }

    public final String repr()
    {
        StringBuffer str = new StringBuffer();
        int i = 0;
        int j = 0;

        while(i < this.size())
        {
            while(j < this.get(i).size())
            {
                str.append(String.valueOf(this.get(i).get(j)));
                str.append(" ");
                j += 1;
            }
            j = 0;
            str.append("\n");
            i += 1;
        }

        return str.toString();
    }
}
我找不到任何语义错误,但eclipse引发了以下错误:

//input
1 2 3
4 5 6
//two different matrices
7 8 9
10 11 12
//end input
1.0 2.0 3.0
4.0 5.0 6.0

7.0 8.0 9.0
10.0 11.0 12.0
Exception in thread "main"
0, 0: 1.0 + 7.0 = 8.0
0, 1: 3.0 + 8.0 = 11.0
0, 2: java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at informatica.python.TwoDimensionalArrayList.getFromInnerArray(TwoDimensionalArrayList.java:37)
at informatica.Matrix.getValue(Matrix.java:62)
at informatica.Matrix.sum(Matrix.java:105)
at informatica.App.main(App.java:25)
就我所见,一个指数似乎是独立的,我不明白为什么它以2:1.0+7.0递增,两者都是(0,0),但3.0+8.0分别是(0,2)和(0,1)。我真的不知道为什么会这样


提前感谢。

因为您正在缩小列表并在此处使用索引覆盖值:

public void setToInnerArray(int index, int index2, T t)
{
    this.removeFromInnerArray(index, index2);//1
    this.addToInnerArray(index, index2, t);//2
}
如果我通过索引=0,索引2为0,值t为10,并且我在上面提到的arrayList中有[3,4],那么将:

  • 从索引0中删除3,该索引在第0个索引中留下[4]的arraylist
  • 将10设置为索引0,这意味着您只剩下[10]

  • 你的问题就在这里:

    public void addToInnerArray(int index, int index2, T element) {
        while (index >= this.size()) {
            this.add(new ArrayList<T>());
        }
    
        ArrayList<T> inner = this.get(index);
        while (index2 >= inner.size()) {
            inner.add(null);
        }
    
        inner.set(index2, element); // <- this line
    }
    

    您可以尝试熟悉调试器的使用,因为调试器在这种情况下可以帮助您。

    问题是您在操作过程中更改了矩阵。你打电话

    a.sum(b);
    
    哪个叫

    for (int i = 0; i < this.nrows; i++) {
        for (int j = 0; j < this.ncolumns; j++) {
            System.out.print(i + ", " + j + ": ");
            System.out.print(this.getValue(i, j) + " + " + b.getValue(i, j) + " = ");
            Double r = (Double) (double) Math.round((this.getValue(i, j) + b.getValue(i, j)) * 1000) / 1000;
            System.out.println(r);
            this.setValue(i, j, r);
        }
    }
    

    Edit:如其他答案中所述,导致问题的精确行在方法
    addtoInneraray
    中,该方法在
    this.setValue
    中调用。然而,当您想要执行重用索引的乘法时,您无论如何都不会得到正确的结果(异常与否),因为您正在动态地更改输入。使用静态方法作为操作(
    sum
    scalarProduct
    vectorProd
    等)的设计将确保这不会成为问题。

    您最好的选择是在计算过程中使用调试器并逐行执行(对于任何错误都是如此)首先,我认为对矩阵使用
    ArrayList
    是个坏主意。因为
    ArrayList
    总是比它包含的数据大,所以会有很多内存开销。矩阵是低级组件,应该使用低级数据结构来实现。TwoDimensionalArrayList.addToInnerArray是假的。如何确保只添加一个元素就可以生成get(index)?可能索引-this.size()>1。您必须添加尽可能多的新元素才能创建this.size()>索引。如前所述,您的设计不适合您的需要。这里有几个设计问题。您应该扩展ArrayList。您应该在内部使用一个。但事实上,由于您事先知道矩阵的大小,因此使用ArrayList是过分的,并且使事情比使用简单的2D数组更复杂。我还可以避免在执行操作时修改操作数。相反,sum()应该保持这两个矩阵不变,并返回一个新矩阵。
    在索引0处添加10,这意味着您剩下的[10]
    不太正确。如果您添加它,您将得到
    [10,4]
    。问题是,OP使用的是
    set
    inner.add(index2, element); // "add" instead of "set"
    
    a.sum(b);
    
    for (int i = 0; i < this.nrows; i++) {
        for (int j = 0; j < this.ncolumns; j++) {
            System.out.print(i + ", " + j + ": ");
            System.out.print(this.getValue(i, j) + " + " + b.getValue(i, j) + " = ");
            Double r = (Double) (double) Math.round((this.getValue(i, j) + b.getValue(i, j)) * 1000) / 1000;
            System.out.println(r);
            this.setValue(i, j, r);
        }
    }
    
    Matrix result = Matrix.sum(a, b);