Таблица, подобная структуре данных Java
Мне нужно реализовать некоторую табличную структуру данных, которая хранит такую информацию в Java:
+--------+-------+-----+
| sij | i | j |
+--------+-------+-----+
| 45 | 5 | 7 |
+--------+-------+-----+
| 33 | 1 | 6 |
+--------+-------+-----+
| 31 | 0 | 9 |
+--------+-------+-----+
| 12 | 8 | 2 |
+--------+-------+-----+
и я должен иметь возможность сортировать таблицу с помощью параметра sij
. Я провел несколько тестов с ArrayList
и HashMap
, но я не могу заставить их работать хорошо.
Ответы
Ответ 1
Существует общий TreeBasedTable
класс из Google guava библиотека, которая делает именно то, что вы просите. Он также предлагает множество других полезных методов утилиты, и его использование показано в руководстве пользователя.
Из TreeBasedTable
docs:
Реализация таблицы, ключи которой и ключи столбцов упорядочены по их естественному порядку или по предоставленным компараторам.
Пример использования:
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]
Ответ 2
Что вы имеете в виду:
Я должен иметь возможность сортировать его по параметру sij
Что случилось с:
Object [][] data
ИЗМЕНИТЬ
Хорошо, просто угадывая, что вам нужна "StrangeDataStructure", которая содержит массив, и помогает сортировать по первому столбцу, тогда единственное, что вам нужно, это что-то вроде этого:
class Structure {
Object [][] data;
Object [] indexColumn; // the sij?
}
И что это: вы должны добавить метод сортировки, указывающий направление, и отсортировать с помощью "indexColumn"
Это VEEERY просто, я думаю (и если я понял ваш "вопрос" )
Знаешь что? Я собираюсь реализовать его.
//время истекает...
Вот он:
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
}
Вывод:
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,
Ответ 3
Прочтите раздел из руководства Swing по Как использовать таблицы. В учебном пособии показано, как создать таблицу, а также как добавить в таблицу возможность сортировки.
Если вам нужно только сохранить данные, но не отобразить их, тогда вы можете использовать двумерный массив или список списков. Затем вы можете использовать Column Comparator для сортировки.
Изменить: добавлен код, демонстрирующий использование 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) );
}
}
}
Я также согласен с предложением создать объект для хранения трех переменных. В этом случае вы можете использовать BeanComparator, который можно найти по приведенной выше ссылке.
Ответ 4
Вы можете использовать MultiValueMap из Apache, чтобы связать несколько значений с одним ключом.
Ответ 5
Один из вариантов - создать новый объект, содержащий 3 переменные, а затем создать массив/дерево этих объектов и отсортировать по требуемому параметру.
Ответ 6
Здесь один из способов: создать объект с именем Row для хранения каждой строки, а затем создать java.util.HashMap, чьими ключами являются Integer sij и значениями которых являются соответствующие строки.
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);
}
}
}
При этом выполняется:
sij: 12 i: 8 j: 2
sij: 31 i: 0 j: 9
sij: 33 i: 1 j: 6
sij: 45 i: 5 j: 7
Ответ 7
Если я правильно понимаю ваш вопрос, все, что вам нужно, это класс Comparable
для представления строки.
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;
}
Затем вы можете заполнить List
экземплярами Row
и использовать Collections.sort
для сортировки.