2011-02-05 44 views
40

En Java, tengo un dato en mi matriz como la siguienteOrdenar una matriz bidimensional basado en una columna

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 

me gustaría resolverlo en base a la primera columna, por lo que mis datos finales pueden buscar como esto

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 primera columna es una fecha de formato "aaaa.mm.dd HH: mm" y la segunda columna es una cadena.

Respuesta

70

Ordenar una matriz bidimensional basado en una columna
La primera columna es una fecha de formato "aaaa.mm.dd HH: mm" y la segunda columna es una Cadena.

Como dices matriz 2-D, supongo que "fecha de formato ..." significa una cadena.Aquí está el código para la clasificación de una matriz 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]); 
     } 
    } 

} 

de salida:

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! Lo probé y funcionó como se esperaba - gracias - marcando como la respuesta correcta – emaillenin

+0

@emaillenin - Me alegro de poder ayudar –

+0

@BertF, útil. Si quiero comparar en orden natural, ¿qué debo hacer? Y +1 por buena respuesta. :) –

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 este won compilar Debería ser sort (array, comparador). – dogbane

+3

Editado por la corrección de @ dogbane. –

5

Asumiendo que su matriz contiene cadenas, puede utilizar el siguiente:

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 tiene una matriz de dos dimensiones, la solución también es muy similar:

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 dice que es una matriz 2D. – dogbane

+0

@dogbane Echa un vistazo a la pregunta. * No * en realidad es una matriz 2D, aunque el título insiste en que sí lo es. Es una matriz de 'String's con datos columnares dentro. De hecho, esta respuesta aborda la pregunta real mejor que todas las demás ... – dkarp

+1

@dkarp ¿por qué estás comparando los tiempos? Debe comparar la primera columna que es "aaaa.MM.dd HH: mm". Eche otro vistazo a la pregunta. – 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 esta manera puede manejar cualquier tipo de datos en esas matrices (siempre y cuando sean Comparables) y puede ordenar cualquier columna en asc orden final o descendente.

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

PS: asegúrese de comprobar para ArrayIndexOutOfBounds y otros.

EDIT: La solución anterior sólo sería útil si usted es capaz de almacenar una realidad java.util.Date en la primera columna o si su formato de fecha permite el uso de comparación de cadenas sin formato para esos valores. De lo contrario, debe convertir esa cadena en una fecha, y puede lograr eso usando una interfaz de devolución de llamada (como una solución general). Aquí está una versión mejorada:

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

Y en este punto, se puede ordenar en su primera columna con:

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

me he saltado los controles para los nulos y otros asuntos de manejo de errores.

Acepto que esto ya empieza a parecer un framework. :)

Última edición (afortunadamente): ahora me doy cuenta de que el formato de fecha le permite utilizar la comparación de cadena simple. Si ese es el caso, no necesita la "versión mejorada".

+1

+1, para la solución más general para ordenar por cualquier objeto y en cualquier columna. – camickr

+0

Es una buena solución general, pero la pregunta planteada pide la clasificación de un 'String []' donde cada 'String' contiene datos en columnas. El título no coincide con la pregunta; esta respuesta satisface el título solo ... – dkarp

+2

buena escritura, pero eso es un montón de código – Ron

3

Compruebe el ColumnComparator. Básicamente es la misma solución propuesta por Costi, pero también admite la clasificación en columnas en una lista y tiene algunas propiedades de clasificación más.

4
  1. instalar java8 JDK + jre

  2. uso expresión lambda para ordenar matriz 2D.

código:

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

salida

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

Usando Lambdas desde 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)); 

de salida:

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

Cuestiones relacionadas