像Java数据结构中的表格

31

我需要在Java中实现一种类似表格的数据结构,用于存储以下信息:

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

我必须能够通过参数对表进行排序。我已经使用ArrayListHashMap进行了一些测试,但是我无法使它们正常工作。


你的意思是必须按照第一列中的值对行进行排序吗? - Bill the Lizard
准确地说!通过sij参数。 - Sverd
@Bill the Lizard:他在说什么? - OscarRyz
希望你能帮助我!你具体想要我们如何帮助你呢? - abelenky
我稍微澄清了一下语言,希望没有扭曲它。 - Jim Ferrans
显示剩余2条评论
7个回答

27

有一个通用的 TreeBasedTable 类来自于 Google 库,它完全满足你所要求的功能。它还提供了许多其他有用的实用方法,并且其使用方法在用户指南中有详细介绍。

TreeBasedTable 文档中可以看到:

Table 的实现方式,其行键和列键按其自然顺序或提供的比较器进行排序。

示例用法:

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]

21

你说的意思是什么:

我必须能够按照sij参数进行排序

这样做有什么问题吗:

Object [][] data

编辑

好的,我猜想你需要一个名为 "StrangeDataStructure" 的数据结构来保存数组,并帮助你按照第一列排序,那么你所需要的就是像这样的东西:

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

就是这样:您应该添加一个指示方向的排序方法,并使用“indexColumn”进行排序。

我认为这非常简单(如果我理解了您的“问题”)。

你知道吗?我要实现它。

// 时间流逝...

这就是它:

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,

嗨,感谢回答。sij参数是从i和j派生出来的值,就像它们之间的距离一样。使用数组矩阵,我会失去参考。想象一下,如果我需要按“sij”从小到大排序:我想得到: 12 8 2 31 0 9 等等 - Sverd
3
我还不理解。对你来说可能很明显,因为你一直在做这个,但对我来说不是。如果你用例子进一步解释一下sij是什么,你会得到更好的答案。请点击您原帖中的“编辑”并进行解释。使用例子总是有效的。 - OscarRyz

4

阅读Swing教程中关于如何使用表格的部分。该教程展示了如何创建表格以及如何为表格添加排序功能。

如果您只需要存储数据而不需要显示它,则可以使用二维数组或列表列表。然后,您可以使用列比较器进行排序。

编辑:添加了演示使用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) );
        }
    }
}

我也同意创建一个对象来存储这3个变量的建议。在这种情况下,您可以使用上面链接中找到的BeanComparator

2
这里有一种方法:创建一个名为"Row"的对象来保存每一行,然后创建一个java.util.HashMap,其键为整数sij,值为相应的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);
    }
  }
}

当运行时,它会生成以下内容:
sij: 12 i: 8 j: 2
sij: 31 i: 0 j: 9
sij: 33 i: 1 j: 6
sij: 45 i: 5 j: 7

2
如果我理解你的问题正确,你所需要的只是一个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对其进行排序。

但是如果我想要一个通用的表格呢? - Raja Anbazhagan
1
不确定为什么你会因此被点踩,这基本上是教科书上的解决方案。 - Coder375

2
你可以使用Apache的MultiValueMap,将多个值与一个键链接起来。

很遗憾,MultiValueMap 没有排序。 - finnw

1
一种选择是创建一个包含3个变量的新对象,然后将这些对象制作成数组/树,并按照所需参数进行排序。

好主意。那我怎么在数组中排序呢? - Sverd
Google 快速排序或归并排序 - user181494

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接