2010-06-18 14 views
11

Tengo un programa Java simple que lee un directorio de archivos y genera una lista de archivos. puedo ordenar los archivos por nombre:Ordenar archivos por nombre en Java difiere de Windows Explorer

String [] files = dirlist.list(); 
files = sort(files); 

Mi problema es que se ordena por el nombre de una manera diferente a la del Explorador de Windows lo hace.

Por ejemplo, si tengo estos archivos: abc1.doc, abc12.doc, abc2.doc.

Java clasificará como esto:

abc1.doc 
abc12.doc 
abc2.doc 

Al abrir la carpeta en el Explorador de Windows, los archivos se ordenan así:

abc1.doc 
abc2.doc 
abc12.doc 

¿Cómo puedo hacer Java ordenar mis archivos al igual que en ¿Explorador de Windows? ¿Es este un truco de Windows?

+2

Ver http://stackoverflow.com/questions/442429/windows-explorer-sort-method –

Respuesta

18

Windows Explorer usa su propio algoritmo. Con el fin de ordenar los archivos como el Explorador hace, se debe crear un Comparador de encargo para hacer el truco:

public class WindowsExplorerStringComparator implements Comparator<String> 
    { 
     private String str1, str2; 
     private int pos1, pos2, len1, len2; 

     public int compare(String s1, String s2) 
     { 
     str1 = s1; 
     str2 = s2; 
     len1 = str1.length(); 
     len2 = str2.length(); 
     pos1 = pos2 = 0; 

     int result = 0; 
     while (result == 0 && pos1 < len1 && pos2 < len2) 
     { 
      char ch1 = str1.charAt(pos1); 
      char ch2 = str2.charAt(pos2); 

      if (Character.isDigit(ch1)) 
      { 
      result = Character.isDigit(ch2) ? compareNumbers() : -1; 
      } 
      else if (Character.isLetter(ch1)) 
      { 
      result = Character.isLetter(ch2) ? compareOther(true) : 1; 
      } 
      else 
      { 
      result = Character.isDigit(ch2) ? 1 
        : Character.isLetter(ch2) ? -1 
        : compareOther(false); 
      } 

      pos1++; 
      pos2++; 
     } 

     return result == 0 ? len1 - len2 : result; 
     } 

     private int compareNumbers() 
     { 
     int end1 = pos1 + 1; 
     while (end1 < len1 && Character.isDigit(str1.charAt(end1))) 
     { 
      end1++; 
     } 
     int fullLen1 = end1 - pos1; 
     while (pos1 < end1 && str1.charAt(pos1) == '0') 
     { 
      pos1++; 
     } 

     int end2 = pos2 + 1; 
     while (end2 < len2 && Character.isDigit(str2.charAt(end2))) 
     { 
      end2++; 
     } 
     int fullLen2 = end2 - pos2; 
     while (pos2 < end2 && str2.charAt(pos2) == '0') 
     { 
      pos2++; 
     } 

     int delta = (end1 - pos1) - (end2 - pos2); 
     if (delta != 0) 
     { 
      return delta; 
     } 

     while (pos1 < end1 && pos2 < end2) 
     { 
      delta = str1.charAt(pos1++) - str2.charAt(pos2++); 
      if (delta != 0) 
      { 
      return delta; 
      } 
     } 

     pos1--; 
     pos2--; 

     return fullLen2 - fullLen1; 
     } 

     private int compareOther(boolean isLetters) 
     { 
     char ch1 = str1.charAt(pos1); 
     char ch2 = str2.charAt(pos2); 

     if (ch1 == ch2) 
     { 
      return 0; 
     } 

     if (isLetters) 
     { 
      ch1 = Character.toUpperCase(ch1); 
      ch2 = Character.toUpperCase(ch2); 
      if (ch1 != ch2) 
      { 
      ch1 = Character.toLowerCase(ch1); 
      ch2 = Character.toLowerCase(ch2); 
      } 
     } 

     return ch1 - ch2; 
     } 
    } 

Ahora, utilizar de esta manera:

Arrays.sort(files, new WindowsExplorerStringComparator()); 
+1

Gracias! funciona :) –

+0

quería agregar que: el argumento llamado "archivos" debe ser del tipo String [] – kiltek

0

Ordenar por cadena a continuación, por la longitud del nombre.

3

Parece que sí.

Sin embargo, puede usar Arrays.sort() y proporcionar un Comparator personalizado para que tenga el mismo aspecto que Windows Explorer.

0

Esta es otra oportunidad para implementarlo en Java:

Java - Sort Strings like Windows Explorer

En resumen, divide las dos cadenas para comparar en la Carta - Partes dígito y compara estas piezas de un modo específico para lograr este tipo de clasificación.

Con esto es un poco más legible en mi humilde opinión.

Cuestiones relacionadas