2011-02-05 4 views
40

En Java, j'ai données dans mon tableau comme leTrier un tableau à deux dimensions basé sur une colonne

2009.07.25 20:24 Message A 
2009.07.25 20:17 Message G 
2009.07.25 20:25 Message B 
2009.07.25 20:30 Message D 
2009.07.25 20:01 Message F 
2009.07.25 21:08 Message E 
2009.07.25 19:54 Message R 

Je suit que de faire le tri en fonction de la première colonne, donc mes données finales peuvent regarder comme celui-ci

2009.07.25 19:54 Message R 
2009.07.25 20:01 Message F 
2009.07.25 20:17 Message G 
2009.07.25 20:24 Message A 
2009.07.25 20:25 Message B 
2009.07.25 20:30 Message D 
2009.07.25 21:08 Message E 

la première colonne est une date de format « aAAA.MM.JJ HH: mm » et la deuxième colonne est une chaîne.

Répondre

70

Trier un tableau à deux dimensions basé sur une colonne
La première colonne est une date de format « AAAA.MM.JJ HH: mm » et la deuxième colonne est une chaîne.

Puisque vous parlez de tableau 2-D, je suppose que "date de format ..." signifie une chaîne.Voici le code pour le tri d'un tableau 2-D de String [] []:

import java.util.Arrays; 
import java.util.Comparator; 

public class Asdf { 

    public static void main(final String[] args) { 
     final String[][] data = new String[][] { 
       new String[] { "2009.07.25 20:24", "Message A" }, 
       new String[] { "2009.07.25 20:17", "Message G" }, 
       new String[] { "2009.07.25 20:25", "Message B" }, 
       new String[] { "2009.07.25 20:30", "Message D" }, 
       new String[] { "2009.07.25 20:01", "Message F" }, 
       new String[] { "2009.07.25 21:08", "Message E" }, 
       new String[] { "2009.07.25 19:54", "Message R" } }; 

     Arrays.sort(data, new Comparator<String[]>() { 
      @Override 
      public int compare(final String[] entry1, final String[] entry2) { 
       final String time1 = entry1[0]; 
       final String time2 = entry2[0]; 
       return time1.compareTo(time2); 
      } 
     }); 

     for (final String[] s : data) { 
      System.out.println(s[0] + " " + s[1]); 
     } 
    } 

} 

Sortie:

2009.07.25 19:54 Message R 
2009.07.25 20:01 Message F 
2009.07.25 20:17 Message G 
2009.07.25 20:24 Message A 
2009.07.25 20:25 Message B 
2009.07.25 20:30 Message D 
2009.07.25 21:08 Message E 
+2

simple! Je l'ai essayé et cela a fonctionné comme prévu - merci - marquage comme la bonne réponse – emaillenin

+0

@emaillenin - Je suis heureux que je pourrais aider –

+0

@BertF, Utile. Si je veux comparer dans l'ordre naturel, que dois-je faire? Et +1 pour une bonne réponse. :) –

8
Arrays.sort(yourarray, new Comparator() { 
    public int compare(Object o1, Object o2) { 
     String[] elt1 = (String[])o1; 
     String[] elt2 = (String[])o2; 
     return elt1[0].compareTo(elt2[0]); 
    } 
}); 
+2

-1 ce won compile pas. Devrait être tri (tableau, comparateur). – dogbane

+3

Modifié par la correction de @ dogbane. –

5

En supposant que votre tableau contient des chaînes, vous pouvez utiliser les éléments suivants:

String[] data = new String[] { 
    "2009.07.25 20:24 Message A", 
    "2009.07.25 20:17 Message G", 
    "2009.07.25 20:25 Message B", 
    "2009.07.25 20:30 Message D", 
    "2009.07.25 20:01 Message F", 
    "2009.07.25 21:08 Message E", 
    "2009.07.25 19:54 Message R" 
}; 

Arrays.sort(data, new Comparator<String>() { 
    @Override 
    public int compare(String s1, String s2) { 
     String t1 = s1.substring(0, 16); // date/time of s1 
     String t2 = s2.substring(0, 16); // date/time of s2 
     return t1.compareTo(t2); 
    } 
}); 

Si vous avez un tableau à deux dimensions, la solution est également très similaire:

String[][] data = new String[][] { 
     { "2009.07.25 20:17", "Message G" }, 
     { "2009.07.25 20:25", "Message B" }, 
     { "2009.07.25 20:30", "Message D" }, 
     { "2009.07.25 20:01", "Message F" }, 
     { "2009.07.25 21:08", "Message E" }, 
     { "2009.07.25 19:54", "Message R" } 
}; 

Arrays.sort(data, new Comparator<String[]>() { 
    @Override 
    public int compare(String[] s1, String[] s2) { 
     String t1 = s1[0]; 
     String t2 = s2[0]; 
     return t1.compareTo(t2); 
    } 
}); 
+0

-1 OP dit que c'est un tableau 2D. – dogbane

+0

@dogbane Jetez un coup d'oeil à la question. Ce n'est * pas * en fait un tableau 2D, même si le titre insiste sur le fait. C'est un tableau de 'String's avec des données en colonnes à l'intérieur. En fait, cette réponse adresse mieux la question réelle que toutes les autres ... – dkarp

+1

@dkarp pourquoi comparez-vous juste le temps? Vous devriez comparer la première colonne qui est "yyyy.MM.dd HH: mm". Jetez un autre coup d'oeil à la question. – dogbane

11
class ArrayComparator implements Comparator<Comparable[]> { 
    private final int columnToSort; 
    private final boolean ascending; 

    public ArrayComparator(int columnToSort, boolean ascending) { 
     this.columnToSort = columnToSort; 
     this.ascending = ascending; 
    } 

    public int compare(Comparable[] c1, Comparable[] c2) { 
     int cmp = c1[columnToSort].compareTo(c2[columnToSort]); 
     return ascending ? cmp : -cmp; 
    } 
} 

De cette façon, vous pouvez gérer n'importe quel type de données dans ces tableaux (à condition qu'ils soient comparables) et vous pouvez trier n'importe quelle colonne dans asc fin ou décroissant.

String[][] data = getData(); 
Arrays.sort(data, new ArrayComparator(0, true)); 

PS: assurez-vous de vérifier les ArrayIndexOutOfBounds et d'autres.

EDIT: La solution ci-dessus serait utile que si vous êtes en mesure de stocker en fait un java.util.Date dans la première colonne ou si votre format de date vous permet d'utiliser la comparaison de chaîne simple pour les valeurs. Sinon, vous devez convertir cette chaîne en date, et vous pouvez le faire en utilisant une interface de rappel (en tant que solution générale). Voici une version améliorée:

class ArrayComparator implements Comparator<Object[]> { 
    private static Converter DEFAULT_CONVERTER = new Converter() { 
     @Override 
     public Comparable convert(Object o) { 
      // simply assume the object is Comparable 
      return (Comparable) o; 
     } 
    }; 
    private final int columnToSort; 
    private final boolean ascending; 
    private final Converter converter; 


    public ArrayComparator(int columnToSort, boolean ascending) { 
     this(columnToSort, ascending, DEFAULT_CONVERTER); 
    } 

    public ArrayComparator(int columnToSort, boolean ascending, Converter converter) { 
     this.columnToSort = columnToSort; 
     this.ascending = ascending; 
     this.converter = converter; 
    } 

    public int compare(Object[] o1, Object[] o2) { 
     Comparable c1 = converter.convert(o1[columnToSort]); 
     Comparable c2 = converter.convert(o2[columnToSort]); 
     int cmp = c1.compareTo(c2); 
     return ascending ? cmp : -cmp; 
    } 

} 

interface Converter { 
    Comparable convert(Object o); 
} 

class DateConverter implements Converter { 
    private static final DateFormat df = new SimpleDateFormat("yyyy.MM.dd hh:mm"); 

    @Override 
    public Comparable convert(Object o) { 
     try { 
      return df.parse(o.toString()); 
     } catch (ParseException e) { 
      throw new IllegalArgumentException(e); 
     } 
    } 
} 

Et à ce moment, vous pouvez trier votre première colonne avec:

Arrays.sort(data, new ArrayComparator(0, true, new DateConverter()); 

J'Ignoré vérifie et d'autres problèmes nulls de gestion des erreurs.

Je suis d'accord que cela commence déjà à ressembler à un framework. :)

Dernière (heureusement) éditer: Je réalise seulement maintenant que votre format de date vous permet d'utiliser la comparaison de chaîne simple. Si tel est le cas, vous n'avez pas besoin de la "version améliorée".

+1

+1, pour la solution plus générale de trier par n'importe quel objet et sur n'importe quelle colonne. – camickr

+0

C'est une bonne solution générale, mais la question posée demande un tri de 'String []' où chaque 'String' contient des données en colonne. Le titre ne correspond pas à la question; cette réponse satisfait le titre seulement ... – dkarp

+2

bon écrit, mais c'est beaucoup de code – Ron

3

Consultez le ColumnComparator. Il s'agit essentiellement de la même solution que celle proposée par Costi, mais il prend également en charge le tri des colonnes dans une liste et possède quelques propriétés de tri supplémentaires.

4
  1. installer java8 jdk + jre

  2. utilisation expression lamda pour trier Tableau 2D.

code:

import java.util.Arrays; 
import java.util.Comparator; 

class SortString { 

    public static void main(final String[] args) { 
     final String[][] data = new String[][] { 
       new String[] { "2009.07.25 20:24", "Message A" }, 
       new String[] { "2009.07.25 20:17", "Message G" }, 
       new String[] { "2009.07.25 20:25", "Message B" }, 
       new String[] { "2009.07.25 20:30", "Message D" }, 
       new String[] { "2009.07.25 20:01", "Message F" }, 
       new String[] { "2009.07.25 21:08", "Message E" }, 
       new String[] { "2009.07.25 19:54", "Message R" } 
     }; 
     // this is applicable only in java 8 version. 
     Arrays.sort(data, (String[] s1, String[] s2) -> s1[0].compareTo(s2[0])); 

     // we can also use Comparator.comparing and point to Comparable value we want to use   
     // Arrays.sort(data, Comparator.comparing(row->row[0])); 

     for (final String[] s : data) { 
      System.out.println(s[0] + " " + s[1]); 
     } 
    } 
} 

sortie

2009.07.25 19:54 Message R 
2009.07.25 20:01 Message F 
2009.07.25 20:17 Message G 
2009.07.25 20:24 Message A 
2009.07.25 20:25 Message B 
2009.07.25 20:30 Message D 
2009.07.25 21:08 Message E 
2

Utilisation lambdas depuis java 8:

final String[][] data = new String[][] { new String[] { "2009.07.25 20:24", "Message A" }, 
     new String[] { "2009.07.25 20:17", "Message G" }, new String[] { "2009.07.25 20:25", "Message B" }, 
     new String[] { "2009.07.25 20:30", "Message D" }, new String[] { "2009.07.25 20:01", "Message F" }, 
     new String[] { "2009.07.25 21:08", "Message E" }, new String[] { "2009.07.25 19:54", "Message R" } }; 
String[][] out = Arrays.stream(data).sorted(Comparator.comparing(x -> x[1])).toArray(String[][]::new); 

System.out.println(Arrays.deepToString(out)); 

sortie:

[[2009.07.25 20:24, Message A], [2009.07.25 20:25, Message B], [2009.07.25 20:30, Message D], [2009.07.25 21:08, Message E], [25/07/2009 20:01, un message F], [25/07/2009 20:17, un message G], [25/07/2009 19:54, un message R]]

Questions connexes