Ordinamento delle stringhe in base ai numeri contenuti in Java

1. Introduzione

In questo tutorial, vedremo come ordinare le stringhe alfanumeriche in base ai numeri che contengono. Ci concentreremo sulla rimozione di tutti i caratteri non numerici dalla stringa prima di ordinare più stringhe in base ai caratteri numerici rimanenti.

Esamineremo i casi limite comuni, comprese le stringhe vuote e i numeri non validi.

Infine, effettueremo un test unitario della nostra soluzione per assicurarci che funzioni come previsto.

2. Delineare il problema

Prima di iniziare, dobbiamo descrivere ciò che vogliamo che il nostro codice ottenga. Per questo particolare problema, faremo le seguenti ipotesi:

  1. Le nostre stringhe possono contenere solo numeri, solo lettere o un mix dei due.
  2. I numeri nelle nostre stringhe possono essere interi o doppi.
  3. Quando i numeri in una stringa sono separati da lettere, dovremmo rimuovere la lettera e condensare insieme le cifre. Ad esempio, 2d3 diventa 23.
  4. Per semplicità, quando appare un numero non valido o mancante, dovremmo trattarli come 0.

Una volta stabilito questo, rimaniamo bloccati nella nostra soluzione.

3. Una soluzione Regex

Poiché il nostro primo passo è cercare modelli numerici all'interno della nostra stringa di input , possiamo utilizzare espressioni regolari, comunemente note come regex.

La prima cosa di cui abbiamo bisogno è la nostra regex. Vogliamo conservare tutti i numeri interi così come i punti decimali dalla stringa di input . Possiamo raggiungere il nostro obiettivo con quanto segue:

String DIGIT_AND_DECIMAL_REGEX = "[^\\d.]" String digitsOnly = input.replaceAll(DIGIT_AND_DECIMAL_REGEX, "");

Spieghiamo brevemente cosa sta succedendo:

  1. '[^]' - denota un insieme negato, quindi prende di mira qualsiasi carattere non specificato dalla regex inclusa
  2. '\ d' : corrisponde a qualsiasi carattere numerico (0-9)
  3. "." - corrisponde a qualsiasi "." personaggio

Quindi utilizziamo il metodo String.replaceAll per rimuovere qualsiasi carattere non specificato dalla nostra regex. In questo modo, possiamo garantire che i primi tre punti del nostro obiettivo possano essere raggiunti.

Successivamente, è necessario aggiungere alcune condizioni per garantire che le stringhe vuote e non valide restituiscano 0, mentre le stringhe valide restituiscono un Double valido :

if("".equals(digitsOnly)) return 0; try { return Double.parseDouble(digitsOnly); } catch (NumberFormatException nfe) { return 0; }

Questo completa la nostra logica. Tutto ciò che resta da fare è collegarlo a un comparatore in modo da poter ordinare comodamente gli elenchi di stringhe di input .

Creiamo un metodo efficiente per restituire il nostro comparatore da qualsiasi luogo lo desideriamo:

public static Comparator createNaturalOrderRegexComparator() { return Comparator.comparingDouble(NaturalOrderComparators::parseStringToNumber); }

4. Prova, prova, prova

A cosa serve il codice senza test per verificarne la funzionalità? Impostiamo un rapido unit test per assicurarci che tutto funzioni come pianificato:

List testStrings = Arrays.asList("a1", "d2.2", "b3", "d2.3.3d", "c4", "d2.f4",); // 1, 2.2, 3, 0, 4, 2.4 testStrings.sort(NaturalOrderComparators.createNaturalOrderRegexComparator()); List expected = Arrays.asList("d2.3.3d", "a1", "d2.2", "d2.f4", "b3", "c4"); assertEquals(expected, testStrings);

In questo test unitario, abbiamo inserito tutti gli scenari che abbiamo pianificato. Numeri, interi, decimali e numeri separati da lettere non validi sono tutti inclusi nella nostra variabile testStrings .

5. conclusione

In questo breve articolo, abbiamo dimostrato come ordinare le stringhe alfanumeriche in base ai numeri al loro interno, facendo uso di espressioni regolari per fare il duro lavoro per noi.

Abbiamo gestito le eccezioni standard che possono verificarsi durante l'analisi delle stringhe di input e testato i diversi scenari con unit test.

Come sempre, il codice può essere trovato su GitHub.