Sortieren von Zeichenfolgen nach enthaltenen Zahlen in Java

1. Einleitung

In diesem Tutorial sehen wir uns an, wie alphanumerische Zeichenfolgen nach den darin enthaltenen Zahlen sortiert werden . Wir konzentrieren sich auf alle nicht-numerischen Zeichen aus dem Entfernen String vor mehreren Sortier Strings durch die numerischen Zeichen , die bleiben.

Wir werden uns allgemeine Randfälle ansehen, einschließlich leerer Zeichenfolgen und ungültiger Zahlen.

Schließlich werden wir unsere Lösung einem Unit-Test unterziehen, um sicherzustellen, dass sie wie erwartet funktioniert.

2. Das Problem umreißen

Bevor wir beginnen, müssen wir beschreiben, was unser Code erreichen soll. Für dieses spezielle Problem gehen wir von folgenden Annahmen aus:

  1. Unsere Zeichenfolgen dürfen nur Zahlen, nur Buchstaben oder eine Mischung aus beiden enthalten.
  2. Die Zahlen in unseren Zeichenfolgen können ganze oder doppelte Zahlen sein.
  3. Wenn Zahlen in einer Zeichenfolge durch Buchstaben getrennt sind, sollten wir den Buchstaben entfernen und die Ziffern zusammenfassen. Zum Beispiel wird 2d3 zu 23.
  4. Wenn der Einfachheit halber eine ungültige oder fehlende Nummer angezeigt wird, sollten wir sie als 0 behandeln.

Lassen Sie uns mit dieser Lösung in unserer Lösung stecken bleiben.

3. Eine Regex-Lösung

Da unser erster Schritt darin besteht, in unserem Eingabe- String nach numerischen Mustern zu suchen , können wir reguläre Ausdrücke verwenden, die allgemein als Regex bezeichnet werden.

Das erste, was wir brauchen, ist unser Regex. Wir wollen alle ganzen Zahlen sparen sowie Dezimalstellen aus dem Eingang String . Wir können unser Ziel mit Folgendem erreichen:

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

Lassen Sie uns kurz erklären, was passiert:

  1. '[^]' - bezeichnet eine negierte Menge und zielt daher auf alle Zeichen ab, die nicht durch die beigefügte Regex angegeben sind
  2. '\ d' - entspricht einem beliebigen Ziffernzeichen (0 - 9)
  3. '.' - mit jedem "." Charakter

Wir verwenden dann die String.replaceAll- Methode, um alle Zeichen zu entfernen, die nicht in unserem regulären Ausdruck angegeben sind. Auf diese Weise können wir sicherstellen, dass die ersten drei Punkte unseres Ziels erreicht werden.

Als nächstes müssen wir einige Bedingungen hinzufügen, um sicherzustellen, dass leere und ungültige Strings 0 zurückgeben, während gültige Strings ein gültiges Double zurückgeben :

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

Das vervollständigt unsere Logik. Sie müssen es nur noch an einen Komparator anschließen, damit wir die Listen der Eingabezeichenfolgen bequem sortieren können .

Lassen Sie uns eine effiziente Methode erstellen, um unseren Komparator von jedem beliebigen Ort zurückzugeben:

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

4. Test, Test, Test

Was nützt Code ohne Tests zur Überprüfung seiner Funktionalität? Lassen Sie uns einen schnellen Komponententest einrichten, um sicherzustellen, dass alles wie geplant funktioniert:

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 diesem Unit-Test haben wir alle geplanten Szenarien zusammengefasst. In unserer Variablen testStrings sind ungültige Zahlen, Ganzzahlen, Dezimalstellen und durch Buchstaben getrennte Zahlen enthalten .

5. Schlussfolgerung

In diesem kurzen Artikel haben wir gezeigt, wie alphanumerische Zeichenfolgen anhand der darin enthaltenen Zahlen sortiert werden. Dabei werden reguläre Ausdrücke verwendet, um die harte Arbeit für uns zu erledigen.

Wir haben Standardausnahmen behandelt, die beim Parsen von Eingabezeichenfolgen auftreten können, und die verschiedenen Szenarien mit Unit-Tests getestet.

Wie immer ist der Code auf GitHub zu finden.