web-dev-qa-db-fra.com

Tableau comme Java structure de données

J'ai besoin d'implémenter une structure de données de type table qui stocke des informations comme celle-ci en Java:

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

et je dois être en mesure de trier la table par le paramètre sij. J'ai fait quelques tests avec ArrayList et HashMap, mais je ne peux pas les faire fonctionner correctement.

25
Sverd

Il existe une classe TreeBasedTable générique de Google guava bibliothèque qui fait exactement ce que vous demandez. Il propose également de nombreuses autres méthodes utilitaires utiles et son utilisation est indiquée dans le guide de l'utilisateur .

À partir des documents TreeBasedTable:

Implémentation de Table dont les clés de ligne et les clés de colonne sont classées par ordre naturel ou par comparateurs fournis.

Exemple d'utilisation:

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]
24
Andrejs

Que voulez-vous dire par:

je dois être en mesure de le trier par le paramètre sij

Quel est le problème avec:

Object [][] data

MODIFIER

Ok, juste deviner que ce dont vous avez besoin est un "StrangeDataStructure" qui contient le tableau et vous aide à trier par la première colonne, puis la seule chose dont vous avez besoin est quelque chose comme ceci:

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

Et c'est tout: vous devez ajouter une méthode de tri indiquant la direction, et trier en utilisant le "indexColumn"

C'est simple VEEERY je pense (et si j'ai compris votre "question" )

Vous savez quoi? Je vais le mettre en œuvre.

// temps écoulé ...

C'est ici:

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
}

Production:

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,
19
OscarRyz

Lisez la section du tutoriel Swing sur Comment utiliser les tableaux . Le didacticiel montre comment créer une table ainsi que comment ajouter une fonction de tri à la table.

Si vous avez seulement besoin de stocker les données mais pas de les afficher, vous pouvez utiliser un tableau à deux dimensions ou une liste de listes. Ensuite, vous pouvez utiliser le comparateur de colonnes pour effectuer le tri.

Edit: ajout de code démontrant l'utilisation du 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) );
        }
    }
}

Je suis également d'accord avec la suggestion de créer un objet pour stocker les 3 variables. Dans ce cas, vous pouvez utiliser le BeanComparator qui se trouve sur le lien ci-dessus.

3
camickr

Vous pouvez utiliser le MultiValueMap d'Apache afin de lier plusieurs valeurs avec une seule clé.

2
Atmocreations

Voici une façon: créez un objet appelé Row pour contenir chaque ligne, puis créez un Java.util.HashMap dont les clés sont des sij entiers et dont les valeurs sont les lignes correspondantes.

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);
    }
  }
}

Lorsqu'il s'exécute, il produit:

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
Jim Ferrans

Si je comprends bien votre question, tout ce dont vous avez besoin est une classe Comparable pour représenter une ligne.

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;
}

Vous pouvez ensuite remplir un List avec des instances de Row et utiliser Collections.sort pour le trier.

1
finnw

Une option consiste à créer un nouvel objet qui contient les 3 variables, puis à créer un tableau/arbre de ces objets et à trier par le paramètre souhaité.

1
user181494