views:

848

answers:

7

hi. I need to implement some kind table-like data structure that stores info like this in Java:

+--------+-------+-----+
|  sij   |   i   |  j  |
+--------+-------+-----+
|   45   |   5   |  7  |
+--------+-------+-----+ 
|   33   |   1   |  6  |
+--------+-------+-----+ 
|   31   |   0   |  9  |
+--------+-------+-----+ 
|   12   |   8   |  2  |
+--------+-------+-----+

and i have to be able to sort the table by the sij parameter. I've made some tests with ArrayList and HashMap, but I can't make them work well.

hope you can help me!

thanks

+1  A: 

What do you mean with:

i have to be able to sort it by the sij parameter

What's wrong with:

Object [][] data

EDIT

Ok, just guessing that what you need is a "StrangeDataStructure" which holds the array, and helps you to sort by the first column, then the only thing that you need is something like this:

class Structure {
    Object [][] data;
    Object [] indexColumn; // the sij?
}

And that's it: you should add a sort method indicating the direction, and sort using the "indexColumn"

It is VEEERY simple I think ( and If I understood your "question" )

You know what? I'm going to implement it.

// time elapses...

Here it is:

import java.util.Comparator;
import java.util.Arrays;

public class StrangeStructure {

    private Integer [][] data;
    private Integer [] sij; // what is sij anyway?

    public StrangeStructure( Integer [][] matrix  ) {
        data = matrix;
        sij = new Integer[ data.length ];
        for( int i = 0 ; i < data.length ; i++ ) {
            sij[i] = data[i][0];
        }
    }

    public void sort( Direction direction  ) {

        Comparator sijComparator  = new DataComparator( direction, true );
        Comparator dataComparator = new DataComparator( direction, false );

        Arrays.sort( sij, sijComparator );
        Arrays.sort( data, dataComparator  );

    }

    public static void main( String [] args ) {

        StrangeStructure s =  
            new StrangeStructure( new Integer[][]{
                                  { 45, 5, 7 }, 
                                  { 33, 1, 6 }, 
                                  { 31, 0, 9 }, 
                                  { 12, 8, 2 }    
                            });

        System.out.printf("Original:\n%s", s );       

        s.sort( Direction.MIN_TO_MAX );  
        System.out.printf("Min to max:\n%s", s );       

        s.sort( Direction.MAX_TO_MIN );  
        System.out.printf("Max to min\n%s", s );       

    }


    public String toString() {
        StringBuilder b = new StringBuilder();
        for( Integer [] row : data ) {
            for( int i : row ) {
                b.append( i+",");
            }
            b.append("\n");
        }
        return b.toString();

    }

}
class DataComparator implements Comparator {

    private Direction direction;
    private boolean isSij;

    public DataComparator( Direction d, boolean isSij ) {
        this.direction = d;
        this.isSij = isSij;
    }

    public int compare( Object one , Object two  ) {
        if( isSij ){
            return doCompare( direction, (Integer) one, (Integer) two );
        } else {
            return doCompare( direction, ((Integer[])one)[0], ((Integer[])two)[0]);
        }
    }
    public int doCompare( Direction d, int one, int two  ) {
        int a = ( d == Direction.MIN_TO_MAX? one: two );
        int b = ( d == Direction.MIN_TO_MAX? two: one ) ;
        return a - b;
    }
    public boolean equals( Object o ) {
        return false;
    }
}



enum Direction{
    MIN_TO_MAX,
    MAX_TO_MIN
}

Output:

Original:
45,5,7,
33,1,6,
31,0,9,
12,8,2,
Min to max:
12,8,2,
31,0,9,
33,1,6,
45,5,7,
Max to min
45,5,7,
33,1,6,
31,0,9,
12,8,2,
OscarRyz
hi, thanks for answer. the sij parameter is a value derived from i and j , like a distance between them.using an array matrix, i will loose the reference. imagine i need to sort by "sij" from min to max : i want to get :12 8 231 0 9etc
Sverd
I still don't get it. It may be obvious to you because you've been working on that, but not for me. I'm sure if you explain further with examples what is that `sij` all about, you'll get better answers. Click on **edit** in your original post and explain that. Using examples always work.
OscarRyz
+1  A: 

Read the section from the Swing tutorial on How to Use Tables. The tutorial shows how to create a table as well as how to add sorting capability to the table.

If you only need to store the data but not display it, then you can use a 2-dimensional array or a List of Lists. Then you can use the Column Comparator to do the sorting.

Edit: added code demonstrating use of the ColumnComparator

import java.util.*;

public class SortSIJ
{
    public static void main(String args[])
    {
        Object[] data = new Object[4];
     data[0] = new Integer[] {45, 5, 7};
     data[1] = new Integer[] {33, 1, 6};
     data[2] = new Integer[] {31, 0, 9};
     data[3] = new Integer[] {12, 8, 2};

     ColumnComparator cc = new ColumnComparator(0);
//   cc.setAscending( false );

     Arrays.sort(data, cc);

     for (Object row: data)
     {
      Integer[] theRow = (Integer[])row;
      System.out.println( Arrays.asList(theRow) );
     }
    }
}

I also agree with the suggestion to create an Object to store the 3 variables. In this case you can use the BeanComparator which can be found at the above link.

camickr
Is that what he needs? ... mhh let's see...
OscarRyz
I'm not sure what you are commenting on, I gave two possible solutions because the question was so vaque I wasn't sure about the exact requirement. But since everyone else is concentrating on the sort aspect I added the demo code.
camickr
+1  A: 

One option is to create a new object that contains the 3 variables, and then make an array/tree of those objects, and sort by the parameter you want.

Matt
great idea. how could i then sort in array?
Sverd
Google Quicksort or Mergesort
Matt
What's wrong with `Collections.sort`?
finnw
+1  A: 

Here's one way: make an object called Row to hold each row, and then make a java.util.HashMap whose keys are Integer sij's and whose values are the corresponding Rows.

public class Example
{
  public static class Row
  {
    public Integer sij;
    public Integer i;
    public Integer j;
    public Row(Integer sij, Integer i, Integer j)
    {
      this.sij = sij;
      this.i = i;
      this.j = j;
    }
  }

  public static void main(String[] args)
  {
    Row r1 = new Row(45, 5, 7);
    Row r2 = new Row(33, 1, 6);
    Row r3 = new Row(31, 0, 9);
    Row r4 = new Row(12, 8, 2);
    Map<Integer, Row> map = new TreeMap<Integer, Row>();
    map.put(r1.sij, r1);
    map.put(r2.sij, r2);
    map.put(r3.sij, r3);
    map.put(r4.sij, r4);
    for ( Row row : map.values() ) {
        System.out.println("sij: " + row.sij + " i: " + row.i + " j: " + row.j);
    }
  }
}

When this runs it produces:

sij: 12 i: 8 j: 2
sij: 31 i: 0 j: 9
sij: 33 i: 1 j: 6
sij: 45 i: 5 j: 7
Jim Ferrans
A: 

You could use the MultiValueMap from Apache in order to link multiple values with one key.

Atmocreations
Unfortunately `MultiValueMap` is not sorted.
finnw
A: 

If I understand your question right, all you need is a Comparable class to represent a row.

public static class Row
implements Comparable<Row> {
  public Row(int sij, int i, int j) {
    this.sij = sij;
    this.i = i;
    this.j = j;
  }

  public int compareTo(Row other) {
    return Integer.valueOf(sij).compareTo(other.sij);
  }

  public final int sij;
  public final int i;
  public final int j;
}

You can then populate a List with instances of Row and use Collections.sort to sort it.

finnw
A: 

HI, i want to thank all people here eho helpme! your comments were very userful

Sverd