Menyusun Rentetan mengikut Nombor yang Terkandung di Java

1. Pengenalan

Dalam tutorial ini, kita akan melihat cara mengisih String alfanumerik dengan nombor yang terkandung di dalamnya. Kita akan memberi tumpuan kepada menghapuskan semua aksara bukan angka dari String sebelum menyusun berbilang Strings oleh watak-watak berangka yang kekal.

Kami akan melihat kes-kes umum, termasuk String kosong dan nombor tidak sah.

Akhirnya, kami akan menguji penyelesaian kami untuk memastikan ia berfungsi seperti yang diharapkan.

2. Menggariskan Masalah

Sebelum memulakan, kita perlu menerangkan apa yang ingin dicapai oleh kod kita. Untuk masalah ini, kami akan membuat andaian berikut:

  1. String kami mungkin hanya mengandungi nombor, huruf atau gabungan keduanya.
  2. Nombor dalam rentetan kita mungkin berupa bilangan bulat atau dua kali ganda.
  3. Apabila nombor dalam rentetan dipisahkan dengan huruf, kita harus mengeluarkan huruf itu dan menyatukan digitnya bersama-sama. Contohnya, 2d3 menjadi 23.
  4. Untuk kesederhanaan, apabila nombor yang tidak sah atau hilang muncul, kita harus menganggapnya sebagai 0.

Dengan ini, mari kita terjebak dalam penyelesaian kita.

3. Penyelesaian Regex

Oleh kerana langkah pertama kami adalah mencari pola angka dalam String input kami , kami dapat menggunakan ungkapan biasa, yang biasanya dikenal sebagai regex.

Perkara pertama yang kita perlukan adalah regex kita. Kami mahu mengekalkan semua bilangan bulat dan titik perpuluhan dari String input . Kami dapat mencapai matlamat kami dengan perkara berikut:

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

Mari terangkan secara ringkas apa yang berlaku:

  1. '[^]' - menunjukkan set yang ditolak, oleh itu menyasarkan watak yang tidak ditentukan oleh regex terlampir
  2. '\ d' - padankan mana-mana watak digit (0 - 9)
  3. '.' - sesuai dengan mana-mana "." watak

Kami kemudian menggunakan kaedah String.replaceAll untuk membuang sebarang watak yang tidak ditentukan oleh regex kami. Dengan melakukan ini, kita dapat memastikan bahawa tiga mata pertama matlamat kita dapat dicapai.

Seterusnya, kita perlu menambah beberapa syarat untuk memastikan kosong dan tidak sah Strings kembali 0, manakala sah Strings kembali yang sah Double :

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

Itu melengkapkan logik kami. Semua itu perlu dilakukan adalah palam ke dalam comparator supaya kita boleh dengan mudah jenis Senarai input Strings.

Mari buat kaedah yang berkesan untuk mengembalikan pembanding kita dari mana sahaja yang kita mahukan:

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

4. Uji, Uji, Uji

Apa kebaikan kod tanpa ujian untuk mengesahkan fungsinya? Mari buat ujian unit cepat untuk memastikan semuanya berfungsi seperti yang kami rancangkan:

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

Dalam ujian unit ini, kami telah membungkus semua senario yang telah kami rancangkan. Nombor, bilangan bulat, perpuluhan, dan nombor yang dipisahkan huruf tidak sah semuanya termasuk dalam pemboleh ubah testStrings kami .

5. Kesimpulan

Dalam artikel pendek ini, kami telah menunjukkan cara menyusun rentetan alfanumerik berdasarkan nombor di dalamnya - menggunakan ungkapan biasa untuk melakukan kerja keras bagi kami.

Kami telah menangani pengecualian standard yang mungkin berlaku semasa menguraikan rentetan input dan menguji senario yang berbeza dengan pengujian unit.

Seperti biasa, kodnya boleh didapati di GitHub.