Reputation: 331
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.
Upvotes: 31
Views: 95369
Reputation: 27687
There is a generic TreeBasedTable
class from Google guava library which does exactly what you are asking for. It also offers many other useful utility methods and its usage is shown in the user guide.
From the TreeBasedTable
docs:
Implementation of Table whose row keys and column keys are ordered by their natural ordering or by supplied comparators.
Example usage:
RowSortedTable<Vertex, Vertex, Double> weightedGraph = TreeBasedTable.create();
weightedGraph.put(v2, v3, 4.0);
weightedGraph.put(v1, v2, 20.0);
System.out.println( weightedGraph.rowKeySet() ); // prints [v1, v2]
Upvotes: 27
Reputation: 48629
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.
Upvotes: 2
Reputation: 10061
You could use the MultiValueMap from Apache in order to link multiple values with one key.
Upvotes: 2
Reputation: 324118
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.
Upvotes: 4
Reputation: 31012
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
Upvotes: 2
Reputation: 199224
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,
Upvotes: 21
Reputation:
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.
Upvotes: 1