1. Przegląd
W tym artykule omówimy różne sposoby porównywania ciągów znaków w Javie.
Ponieważ String jest jednym z najczęściej używanych typów danych w Javie, jest to naturalnie bardzo często używana operacja.
2. Ciąg Porównanie z String Klasa
2.1. Korzystanie z operatora porównania „==”
Używanie operatora „==” do porównywania wartości tekstowych jest jednym z najczęstszych błędów popełnianych przez początkujących programistów Java. Jest to niepoprawne, ponieważ „==” sprawdza tylko referencyjną równość dwóch ciągów , co oznacza, czy odnoszą się one do tego samego obiektu, czy nie.
Zobaczmy przykład takiego zachowania:
String string1 = "using comparison operator"; String string2 = "using comparison operator"; String string3 = new String("using comparison operator"); assertThat(string1 == string2).isTrue(); assertThat(string1 == string3).isFalse();
W powyższym przykładzie pierwsze stwierdzenie jest prawdziwe, ponieważ dwie zmienne wskazują na ten sam literał String .
Z drugiej strony, drugie twierdzenie jest fałszywe, ponieważ łańcuch1 jest tworzony z dosłownym i String3 jest tworzony za pomocą nowego operatora - w związku z tym odwołać się różne przedmioty.
2.2. Używanie równa się ()
String klasy zastępują equals () odziedziczonych z Object. Ta metoda porównuje dwa Strings znak po znaku, ignorując ich adres.
Uważa je za równe, jeśli mają tę samą długość, a znaki są w tej samej kolejności:
String string1 = "using equals method"; String string2 = "using equals method"; String string3 = "using EQUALS method"; String string4 = new String("using equals method"); assertThat(string1.equals(string2)).isTrue(); assertThat(string1.equals(string4)).isTrue(); assertThat(string1.equals(null)).isFalse(); assertThat(string1.equals(string3)).isFalse();
W tym przykładzie zmienne string1 , string2 i string4 są równe, ponieważ mają tę samą wielkość liter i wartość niezależnie od ich adresu.
W przypadku string3 metoda zwraca false, ponieważ uwzględnia wielkość liter.
Ponadto, jeśli którykolwiek z dwóch ciągów ma wartość null , metoda zwraca wartość false.
2.3. Używanie equalsIgnoreCase ()
Metoda equalsIgnoreCase () zwraca wartość logiczną. Jak sama nazwa wskazuje, ta metoda ignoruje wielkość liter w znakach podczas porównywania ciągów znaków :
String string1 = "using equals ignore case"; String string2 = "USING EQUALS IGNORE CASE"; assertThat(string1.equalsIgnoreCase(string2)).isTrue();
2.4. Korzystanie z funkcji compareTo ()
Metoda compareTo () zwraca wartość typu int i porównuje dwa Strings znak po znaku leksykograficznie na podstawie słownika lub porządku naturalnego.
Ta metoda zwraca 0, jeśli dwa Strings są równe lub oba są równe null, liczbę ujemną, jeśli pierwszy String znajduje się przed argumentem, oraz liczbę większą niż zero, jeśli pierwszy String występuje po argumencie String.
Zobaczmy przykład:
String author = "author"; String book = "book"; String duplicateBook = "book"; assertThat(author.compareTo(book)) .isEqualTo(-1); assertThat(book.compareTo(author)) .isEqualTo(1); assertThat(duplicateBook.compareTo(book)) .isEqualTo(0);
2.5. Korzystanie z funkcji compareToIgnoreCase ()
CompareToIgnoreCase () jest podobny do poprzedniego sposobu, z wyjątkiem, że pomija przypadku:
String author = "Author"; String book = "book"; String duplicateBook = "BOOK"; assertThat(author.compareToIgnoreCase(book)) .isEqualTo(-1); assertThat(book.compareToIgnoreCase(author)) .isEqualTo(1); assertThat(duplicateBook.compareToIgnoreCase(book)) .isEqualTo(0);
3. Porównanie ciągów z klasą obiektów
Objects to klasa narzędziowa zawierająca statyczną metodę equals () , przydatną w tym scenariuszu - do porównywania dwóch ciągów znaków.
Metoda zwraca prawdę, jeśli dwa ciągi są równe, porównując je najpierw przy użyciu ich adresu, tj. „ ==” . W konsekwencji, jeśli oba argumenty są zerowe , zwraca prawdę, a jeśli dokładnie jeden argument jest pusty , zwraca fałsz.
W przeciwnym razie po prostu wywołuje metodę equals () klasy typu przekazanego argumentu - która w naszym przypadku jest metodą equals () klasy String . W tej metodzie rozróżniana jest wielkość liter, ponieważ wewnętrznie wywołuje metodę equals () klasy String .
Przetestujmy to:
String string1 = "using objects equals"; String string2 = "using objects equals"; String string3 = new String("using objects equals"); assertThat(Objects.equals(string1, string2)).isTrue(); assertThat(Objects.equals(string1, string3)).isTrue(); assertThat(Objects.equals(null, null)).isTrue(); assertThat(Objects.equals(null, string1)).isFalse();
4. Porównanie ciągów z Apache Commons
Biblioteki Apache Commons zawiera klasę użytkową nazwie StringUtils dla String- powiązanych operacji ; ma to również kilka bardzo korzystnych metod porównywania ciągów .
4.1. Używanie equals () i equalsIgnoreCase ()
Na równi () metoda StringUtils klasie to udoskonalona wersja String metoda klasy równych (), która również uchwyty wartości null:
assertThat(StringUtils.equals(null, null)) .isTrue(); assertThat(StringUtils.equals(null, "equals method")) .isFalse(); assertThat(StringUtils.equals("equals method", "equals method")) .isTrue(); assertThat(StringUtils.equals("equals method", "EQUALS METHOD")) .isFalse();
Metoda equalsIgnoreCase () metody StringUtils zwraca wartość logiczną . Działa podobnie do equals (), z wyjątkiem tego , że ignoruje wielkość liter w ciągach znaków :
assertThat(StringUtils.equalsIgnoreCase("equals method", "equals method")) .isTrue(); assertThat(StringUtils.equalsIgnoreCase("equals method", "EQUALS METHOD")) .isTrue();
4.2. Używanie equalsAny () i equalsAnyIgnoreCase ()
W equalsAny () pierwszego argumentu metody badaniem jest ciąg i drugi Multi-arg typu CharSequence. Metoda zwraca prawdziwe , jeśli którykolwiek z pozostałych podanych ciągów dopasować przeciwko pierwszemu String przypadku wyczuciem.
W przeciwnym razie zwracane jest false:
assertThat(StringUtils.equalsAny(null, null, null)) .isTrue(); assertThat(StringUtils.equalsAny("equals any", "equals any", "any")) .isTrue(); assertThat(StringUtils.equalsAny("equals any", null, "equals any")) .isTrue(); assertThat(StringUtils.equalsAny(null, "equals", "any")) .isFalse(); assertThat(StringUtils.equalsAny("equals any", "EQUALS ANY", "ANY")) .isFalse();
Metoda equalsAnyIgnoreCase () działa podobnie do metody equalsAny () , ale ignoruje wielkość liter :
assertThat(StringUtils.equalsAnyIgnoreCase("ignore case", "IGNORE CASE", "any")).isTrue();
4.3. Korzystanie z funkcji compare () i compareIgnoreCase ()
The compare() method in StringUtils class is a null-safe version of the compareTo() method of String class and handles null values by considering a null value less than a non-null value. Two null values are considered equal.
Furthermore, this method can be used to sort a list of Strings with null entries:
assertThat(StringUtils.compare(null, null)) .isEqualTo(0); assertThat(StringUtils.compare(null, "abc")) .isEqualTo(-1); assertThat(StringUtils.compare("abc", "bbc")) .isEqualTo(-1); assertThat(StringUtils.compare("bbc", "abc")) .isEqualTo(1);
The compareIgnoreCase() method behaves similarly, except it ignores casing:
assertThat(StringUtils.compareIgnoreCase("Abc", "bbc")) .isEqualTo(-1); assertThat(StringUtils.compareIgnoreCase("bbc", "ABC")) .isEqualTo(1); assertThat(StringUtils.compareIgnoreCase("abc", "ABC")) .isEqualTo(0);
Obie metody mogą być również używane z opcją nullIsLess . Jest to trzeci argument logiczny, który decyduje, czy wartości null powinny być uważane za mniejsze, czy nie .
Zerowa wartość jest niższa niż innym String jeśli nullIsLess jest prawdą, a wyższa, jeśli nullIsLess jest fałszywe.
Wypróbujmy to:
assertThat(StringUtils.compare(null, "abc", true)) .isEqualTo(-1); assertThat(StringUtils.compare(null, "abc", false)) .isEqualTo(1);
Metoda compareIgnoreCase () z trzecim argumentem boolowskim działa podobnie, z wyjątkiem ignorowania wielkości liter.
5. Wniosek
W tym krótkim samouczku omówiliśmy różne sposoby porównywania ciągów znaków.
Jak zawsze, kod źródłowy przykładów można znaleźć na GitHub.