Diana Diana - 4 months ago 23
Java Question

Java - implement matrix using HashMap

I am trying to implement a matrix using a hash map but I think I am doing something wrong somewhere.
If I type the following matrix:


4 3

2 1


I get


0 3

0 0


Here's my code:

package matrix;

import java.util.HashMap;

public class SparseMatrix extends AbstractMatrix{

private int x=0; // nr of rows
private int y=0; // nr of columns
private int hashvalue = 0;

public void Index (final int x, final int y)
{
this.x=x;
this.y=y;
hashvalue=((x+"")+(y+"")).hashCode();
}

public boolean equals (final Object obj)
{
if (obj instanceof Index)
{
Index index = (Index) obj;
return ((x==index.x) && (y==index.y));
}
else
return false;
}

public int hashCode()
{
return hashvalue;
}


private int rows;
private int columns;
private HashMap<Index,Double> values;

private boolean validIndex (final int row, final int column)
{
return (row>=0 && row<rows && column>=0 && column<columns);
}


public SparseMatrix(double[][] contents) throws MatrixException {
this(contents.length,contents[0].length);
for (int i=0; i<contents.length; i++)
for (int j=0; j<contents[0].length; j++)
setElement(i,j,contents[i][j]);
}

public SparseMatrix(int rows, int columns) throws MatrixException {
if (rows<1 || columns<1)
throw new MatrixException("Number of rows and columns cannot be less than 1");
this.rows=rows;
this.columns=columns;
this.values=new HashMap<Index,Double>();
}

@Override
public int getNumberOfRows() {
return rows;
}

@Override
public int getNumberOfColumns() {
return columns;
}

@Override
public double getElement(int row, int column) throws MatrixException {
if (!validIndex(row,column))
throw new MatrixException (row,column);
Index index = new Index (row,column);
if (values.containsKey(index))
return values.get(index);
else
return 0;
}

@Override
public void setElement(int row, int column, double value) throws MatrixException {
if (!validIndex(row,column))
throw new MatrixException (row,column);
Index index = new Index(row,column);
if (value==0)
{
if (values.containsKey(index))
values.remove(index);
}
else
values.put(index,value);
}
}


and my main function:

a2 = new SparseMatrix(2,2);
a1.setElement(0,0,4);
a1.setElement(0,1,3);
a1.setElement(1,0,2);
a1.setElement(1,1,1);
for (int i=0; i<a2.getNumberOfRows(); i++)
{
for (int j=0; j<a2.getNumberOfColumns(); j++)
System.out.print (a2.getElement(i, j)+ " ");
System.out.println();
}


Any ideas what I am doing wrong?

Answer
public void Index (final int x, final int y)

It looks like this was supposed to be a constructor of the Index class, but instead it's a method, and I don't see the Index class declared anywhere.

You are assigning an instance of SparseMatrix to a2, but call setElement for a1 :

a2 = new SparseMatrix(2,2);
a1.setElement(0,0,4);
a1.setElement(0,1,3);
a1.setElement(1,0,2);
a1.setElement(1,1,1);

I tried your code, fixing all the compilation errors and not relying on the AbstractMatrix super class (by removing the @Override from all the overridden method and by changing the code at the top of your class into a nested class named Index), and got the desired output :

4.0 3.0 
2.0 1.0 

Here's the nested Index class I used :

static class Index {

    private int x=0; // nr of rows
    private int y=0; // nr of columns
    private int hashvalue = 0;

    public Index (final int x, final int y)
    {
        this.x=x;
        this.y=y;
        hashvalue=((x+"")+(y+"")).hashCode();
    }

    public boolean equals (final Object obj)
    {
        if (obj instanceof Index)
        {
            Index index = (Index) obj;
            return ((x==index.x) && (y==index.y));
        }
        else
            return false;
    }

    public int hashCode()
    {
        return hashvalue;
    }

}
Comments