2010-06-18 1 views
11

Ho un semplice programma Java che legge una directory di file e genera un elenco di file. Ho ordinare i file per nome:Ordina file per nome in Java differisce da Windows Explorer

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

Il mio problema è che si ordina in base al nome in un modo diverso rispetto a Windows Explorer fa.

Per esempio se ho questi file: abc1.doc, abc12.doc, abc2.doc.

Java ordinerà come questo:

abc1.doc 
abc12.doc 
abc2.doc 

Quando ho aperto la cartella in Esplora risorse di Windows, i file sono ordinati in questo modo:

abc1.doc 
abc2.doc 
abc12.doc 

Come posso fare Java ordinamento miei file come in Windows Explorer? Si tratta di un trucco di Windows?

+2

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

risposta

18

Esplora risorse utilizza il proprio algoritmo. Per ordinare i file come Explorer fa, è necessario creare un comparatore personalizzato per fare il trucco:

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

Ora, usare in questo modo:

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

Grazie! funziona :) –

+0

volevo aggiungere che: l'argomento chiamato "files" deve essere di tipo String [] – kiltek

0

Ordina per stringa poi da lunghezza del nome.

3

Sembra così.

Tuttavia, è possibile utilizzare Arrays.sort() e fornire un numero personalizzato Comparator in modo da ordinare come fa Windows Explorer.

0

Questa è un'altra prova per la sua attuazione in Java:

Java - Sort Strings like Windows Explorer

In breve si divide le due stringhe da confrontare nella Lettera - Parti Digit e lo confronta parti in un modo specifico per ottenere questo tipo di ordinamento.

Con questo il suo IMHO è un po 'più leggibile.