java - 迭代多维 ArrayList

标签 java arraylist iteration

我搜索了很多问题的答案,但到目前为止一无所获。

我正在为一些矩阵操作实现一个类。一开始我使用 2x2 数组,它们工作正常,但现在对于一些其他方法,我决定切换到更通用的 2x2 ArrayList。

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

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

然后我的矩阵类是这样的:

import java.util.Scanner;
import java.util.Arrays;
import java.util.ArrayList;
import java.lang.reflect.Array;
import java.lang.Math;

import informatica.python.TwoDimensionalArrayList;

public final class Matrix
{
    private final int nrows;
    private final int ncolumns;
    public final TwoDimensionalArrayList<Double> matrix = new TwoDimensionalArrayList<Double>();
    //private final byte precision = 3;

    Matrix(int rows, int cols)
    {
        this.nrows = rows;
        this.ncolumns = cols;
        /*for(int i = 0; i < this.nrows; i++)
        {
            matrix.add(new ArrayList<Double>());
        }*/
    }

    public final void init()
    {
        Scanner sc = new Scanner(System.in);
        for(int i = 0; i < this.nrows; i++)
        {
            for(int j = 0; j < this.ncolumns; j++)
            {
                matrix.addToInnerArray(i, (Double) sc.nextDouble());
            }
        }
        //sc.close();
    }

    public final void setValue(int row, int col, Double val)
    {
        this.matrix.setToInnerArray(row, col, val);
    }

    public final void setValue(int row, ArrayList<Double> val)
    {
        this.matrix.set(row, val);
    }

    public final void setValue(ArrayList<ArrayList<Double>> val)
    {
        this.matrix.clear();
        for(ArrayList<Double> subList: val)
        {
            this.matrix.add(subList);
        }
    }

    public final Double getValue(int row, int col)
    {
        return this.matrix.getFromInnerArray(row, col);
    }

    public final ArrayList<Double> getValue(int row)
    {
        return this.matrix.get(row);
    }

    public final ArrayList<ArrayList<Double>> getValue()
    {
        return this.matrix;
    }

    /*public final int getPrecision()
    {
        return Math.pow(10,precision);
    }*/

    public final int[] getLength()
    {
        int[] len = new int[2];
        ArrayList<Double> subMatrix = this.matrix.get(0);

        len[0] = this.matrix.size();
        len[1] = subMatrix.size();

        return len;
    }

    public final String repr()
    {
        return this.matrix.repr();
    }

    public final void sum(Matrix b)
    {
        if(Arrays.equals(this.getLength(), b.getLength()))
        {
            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);
                }
            }
        }
        else
        {
            System.err.println("Cannot sum two non-similar matrices.");
        }
    }
}

我写了更多的方法,但逻辑总是相同的(差异、标量积等)。

这是要运行的应用程序:

import informatica.Matrix;
import informatica.python.TwoDimensionalArrayList;

import java.lang.reflect.Array;
import java.util.ArrayList;

class App
{
    public static void main(String[] args)
    {
        Matrix a = new Matrix(2,3);
        Matrix b = new Matrix(2,3);

        a.init();
        b.init();
        System.out.println(a.repr());
        System.out.println(b.repr());

        a.sum(b);
    }
}

我真的找不到任何语义错误,但 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 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
}

您正在使用 setToInnerArrayremoveFromInnerArray 从内部数组列表中删除旧元素,但您没有添加新元素,而是覆盖了现有元素.因此,内部列表保留在 2 而不是 3 元素处。

将提到的行更改为:

inner.add(index2, element); // "add" instead of "set"

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

关于java - 迭代多维 ArrayList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26562107/

相关文章:

java - 如何在nexus7上解压代码

java - 多线程 Java - 线程冲突/覆盖问题

ruby - 跳过 ruby​​ 中 yield block 的迭代

java - 如何在 Java 中对数组求和

java - 如何使用 fireTableDataChanged() 正确更新 AbstractTableModel?

java - 如何使用 JAXB 将 XML 字符串附加到现有的 XML 文件?

java - 如何在实现 Parcelable 时对 ArrayList 进行排序

java - 将列表的列表转换为字符串数组

c++ - 循环内的迭代器初始化是否被认为是不好的风格,为什么?

python - 使用 Python 查找元组中的所有常见元素和组合