Ordinamento delle stringhe che contengono il numero in Java

Ho un problema con il confronto predefinito per le stringhe (in SortedSet). Il problema è che il comparatore di default non ordina una buona stringa che contenga numeri, cioè: Nel set ho:

room1, room2, room100 

L’ordine naturale dovrebbe essere come sopra ma nel set ho:

 room1, room100, room2 

So perché è, ma non so come cambiarlo.

Prova questo comparatore, che rimuove tutti i caratteri non numerici, quindi confronta i restanti caratteri come numeri:

 Collections.sort(strings, new Comparator() { public int compare(String o1, String o2) { return extractInt(o1) - extractInt(o2); } int extractInt(String s) { String num = s.replaceAll("\\D", ""); // return 0 if no digits found return num.isEmpty() ? 0 : Integer.parseInt(num); } }); 

Ecco un test:

 public static void main(String[] args) throws IOException { List strings = Arrays.asList("room1", "foo", "room2", "room100", "room10"); Collections.sort(strings, new Comparator() { public int compare(String o1, String o2) { return extractInt(o1) - extractInt(o2); } int extractInt(String s) { String num = s.replaceAll("\\D", ""); // return 0 if no digits found return num.isEmpty() ? 0 : Integer.parseInt(num); } }); System.out.println(strings); } 

Produzione:

 [foo, room1, room2, room10, room100] 

prova questo. Ho dato per scontato che avrai sempre “spazio” all’inizio della stringa.

  List list = Arrays.asList("room1", "room100", "room2"); Collections.sort(list, new Comparator() { @Override public int compare(String o1, String o2) { return new Integer(o1.replaceAll("room", "")) .compareTo(new Integer(o2.replaceAll("room", ""))); } }); 

Usato @bohemian answer. Sono appena migliorato un po ‘. Questo ha funzionato molto bene per me

  Collections.sort(asdf, new Comparator() { public int compare(String o1, String o2) { String o1StringPart = o1.replaceAll("\\d", ""); String o2StringPart = o2.replaceAll("\\d", ""); if(o1StringPart.equalsIgnoreCase(o2StringPart)) { return extractInt(o1) - extractInt(o2); } return o1.compareTo(o2); } int extractInt(String s) { String num = s.replaceAll("\\D", ""); // return 0 if no digits found return num.isEmpty() ? 0 : Integer.parseInt(num); } }); 

Ecco la mia implementazione di Comparator per un tipo simile: (le stringhe possono iniziare da qualsiasi carattere)

 public class StringNumberComparator implements Comparator{ @Override public int compare(String o1, String o2) { int i1 = this.getRearInt(o1); int i2 = getLeadingInt(o2); String s1 = getTrailingString(o1); String s2 = getTrailingString(o2); if(i1==i2) return s1.compareTo(s2); if(i1>i2) return 1; else if(i1 

È ansible implementare un comparatore e passarlo al costruttore set. Vedi http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Comparator.html .

Se tutte le tue stringhe sono nella forma di stanza [numero] puoi spogliare la “stanza” analizzare il numero e confrontarlo.
In alternativa, puoi memorizzare i numeri interi nel tuo set e stamparli con il prefisso “room”.

Un’alternativa pigra sarebbe quella di far funzionare il comparatore String senza fare nulla in più (definendo il proprio comparatore). Puoi room0001, room0002, room0100 con zeri i numeri all’interno della tua String in questo modo: room0001, room0002, room0100 quindi il comparatore String predefinito funzionerà. Tuttavia, è necessario conoscere il valore numerico massimo in modo da poter adattare il padding di conseguenza.