【问题标题】:Table like java data structure类似java数据结构的表
【发布时间】:2009-11-07 01:53:12
【问题描述】:

我需要实现某种类似表格的数据结构,在 Java 中存储这样的信息:

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

我必须能够通过sij 参数对表格进行排序。我用ArrayListHashMap 做了一些测试,但我不能让它们正常工作。

【问题讨论】:

  • 您的意思是您必须按第一列中的值对行进行排序吗?
  • 没错!通过 sij 参数
  • @Bill the Lizard:他在说什么?
  • 没有部分代码,没有具体问题,只是“希望你能帮助我!”?您究竟希望我们如何帮助您?
  • 我已经稍微澄清了语言,希望不会扭曲它。

标签: java data-structures


【解决方案1】:

Google 库中有一个通用的 TreeBasedTable 类,它完全符合您的要求。它还提供了许多其他有用的实用方法,其用法见user guide

来自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]

【讨论】:

    【解决方案2】:

    你是什么意思:

    我必须能够通过 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 等
    • 我还是不明白。这对你来说可能很明显,因为你一直在努力,但对我来说不是。我敢肯定,如果您通过示例进一步解释sij 的含义,您将获得更好的答案。单击原始帖子中的编辑并进行解释。使用示例总是有效的。
    【解决方案3】:

    阅读 How to Use Tables 上的 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) );
            }
        }
    }
    

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

    【讨论】:

      【解决方案4】:

      这里有一种方法:创建一个名为 Row 的对象来保存每一行,然后创建一个 java.util.HashMap,其键是 Integer 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
      

      【讨论】:

        【解决方案5】:

        您可以使用来自 Apache 的 MultiValueMap 来通过一个键链接多个值。

        【讨论】:

        • 很遗憾MultiValueMap 没有排序。
        【解决方案6】:

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

        【讨论】:

        • 好主意。我怎么能在数组中排序?
        • 谷歌快速排序或合并排序
        【解决方案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;
        }
        

        然后您可以使用Row 的实例填充List 并使用Collections.sort 对其进行排序。

        【讨论】:

        • 但是如果我想要一个通用的表格呢?
        • 不知道为什么你会因此而被否决,它基本上是教科书的解决方案。
        猜你喜欢
        • 1970-01-01
        • 2015-04-11
        • 1970-01-01
        • 1970-01-01
        • 2011-07-04
        • 1970-01-01
        • 2015-08-31
        • 1970-01-01
        • 2012-05-12
        相关资源
        最近更新 更多