CodeGym /Các khóa học /JAVA 25 SELF /So sánh chuỗi: equals, equalsIgnoreCase, compareTo

So sánh chuỗi: equals, equalsIgnoreCase, compareTo

JAVA 25 SELF
Mức độ , Bài học
Có sẵn

1. So sánh tham chiếu và nội dung

Trong Java, chuỗi — là đối tượng chứ không phải kiểu nguyên thủy. Khi bạn khai báo biến ab, chúng có thể trỏ tới cùng một chuỗi trong String Pool. Còn c, được tạo qua constructor, — là một đối tượng khác. Toán tử == so sánh tham chiếu, không phải nội dung.

String a = "hello";
String b = "hello";
String c = new String("hello");

System.out.println(a == b); // true (rất có thể là chuỗi đã intern)
System.out.println(a == c); // false (đối tượng khác nhau)

Minh họa lỗi

String s1 = "Java";
String s2 = new String("Java");
System.out.println(s1 == s2); // false

Mặc dù các chuỗi trông giống hệt nhau, chúng là các đối tượng khác nhau trong bộ nhớ.

2. equals(): so sánh nội dung chuỗi

Để so sánh đúng nội dung, hãy dùng phương thức equals() — nó so sánh từng ký tự (có phân biệt hoa thường).

String s1 = "Java";
String s2 = new String("Java");
System.out.println(s1.equals(s2)); // true

Ví dụ: so sánh mật khẩu

String inputPassword = "Secret123";
String realPassword = "Secret123";
if (inputPassword.equals(realPassword)) 
{
    System.out.println("Truy cập được cấp!");
} 
else 
{
    System.out.println("Mật khẩu không đúng.");
}

Quan trọng!

Nếu ít nhất một đối tượng là null, gọi equals() sẽ dẫn tới NullPointerException. Mẫu an toàn:

if ("cái gì đó".equals(someString)) { ... }

3. equalsIgnoreCase(): so sánh không phân biệt hoa thường

Khi cần bỏ qua phân biệt hoa thường (ví dụ, dữ liệu người dùng nhập), hãy dùng equalsIgnoreCase().

String name1 = "Ivan";
String name2 = "ivan";
System.out.println(name1.equalsIgnoreCase(name2)); // true

Ví dụ: so sánh địa chỉ email

String email1 = "User@Example.com";
String email2 = "user@example.com";
if (email1.equalsIgnoreCase(email2))
{
    System.out.println("Email khớp nhau!");
}

Tóm tắt: equals vs equalsIgnoreCase

Phương thức Phân biệt hoa thường? Ví dụ “Java” vs “java”
equals()
false
equalsIgnoreCase()
Không
true

4. compareTo(): so sánh chuỗi theo thứ tự từ điển

Phương thức compareTo() thực hiện so sánh theo thứ tự từ điển (lexicographic). Trả về số âm nếu chuỗi thứ nhất “nhỏ hơn”, 0 — bằng nhau, số dương — nếu “lớn hơn”.

System.out.println("apple".compareTo("banana")); // < 0
System.out.println("apple".compareTo("apple"));  // 0
System.out.println("banana".compareTo("apple")); // > 0

a.compareTo(b) →
   < 0 — nếu a đứng trước b
   0   — nếu bằng nhau
   > 0 — nếu a đứng sau b
So sánh theo thứ tự từ điển: kết quả compareTo()

Hoạt động như thế nào?

  • So sánh diễn ra từ trái sang phải theo mã Unicode của ký tự.
  • Tại điểm khác biệt đầu tiên, trả về hiệu của mã ký tự.
  • Nếu một chuỗi là tiền tố của chuỗi kia, chuỗi ngắn hơn “nhỏ hơn”.
System.out.println("cat".compareTo("catalog")); // < 0 ("cat" ngắn hơn)
System.out.println("catalog".compareTo("cat")); // > 0

Ví dụ: sắp xếp mảng chuỗi

String[] fruits = {"banana", "apple", "pear"};
Arrays.sort(fruits); // bên trong dùng compareTo()
System.out.println(Arrays.toString(fruits)); // [apple, banana, pear]

compareToIgnoreCase()

System.out.println("Java".compareToIgnoreCase("java")); // 0

5. Các phương thức startsWith() và endsWith()

Các phương thức startsWith()endsWith() kiểm tra phần đầu và phần cuối chuỗi, trả về true/false.

String fileName = "document.pdf";
String url = "https://www.google.com";

System.out.println(fileName.startsWith("doc"));  // true
System.out.println(fileName.endsWith(".txt"));   // false
System.out.println(url.startsWith("https://"));  // true

Dùng để: xác thực định dạng (tên tệp, URL) và lọc theo tiền tố/hậu tố (ví dụ, tất cả ".jpg").

6. Phương thức contains(): tìm chuỗi con

contains(CharSequence s) — cách đơn giản để kiểm tra sự xuất hiện của chuỗi con. Có phân biệt hoa thường.

String text = "Chào mừng đến với thế giới Java!";
System.out.println(text.contains("thế giới"));   // true
System.out.println(text.contains("C++"));        // false

Để bỏ qua phân biệt hoa thường, chuyển cả hai chuỗi về cùng một dạng: toLowerCase()/toUpperCase().

7. Các phương thức toLowerCase() và toUpperCase()

Trả về một chuỗi mới đã được chuyển sang chữ thường hoặc chữ hoa. Hữu ích cho so sánh không phân biệt hoa thường và định dạng.

String title = "Java Programming";
String lower = title.toLowerCase();
String upper = title.toUpperCase();

System.out.println(lower); // java programming
System.out.println(upper); // JAVA PROGRAMMING

8. Phương thức split(): tách chuỗi thành các phần

split(String regex) tách chuỗi theo một delimiter (biểu thức chính quy) và trả về mảng String[].

Ví dụ 1: theo dấu phẩy

String names = "Alex,Maria,Ivan,Elena";
String[] nameArray = names.split(",");
for (String name : nameArray) 
{
    System.out.println(name.trim()); // trim() loại bỏ khoảng trắng có thể có
}
// Kết quả:
// Alex
// Maria
// Ivan
// Elena

Ví dụ 2: theo dấu cách

String sentence = "Tôi đang học Java";
String[] words = sentence.split(" ");
for (String word : words) 
{
    System.out.println(word);
}
// Kết quả:
// Tôi
// đang học
// Java

Lưu ý:

  • Delimiter là regex. Cần escape ký tự đặc biệt (ví dụ, dấu chấm: "\\.").
  • Phương thức luôn trả về mảng, kể cả khi chỉ có một phần tử.

9. Thực hành: so sánh chuỗi trong ứng dụng thực tế

String registeredEmail = "user@example.com";
String registeredPassword = "Secret123";

Scanner console = new Scanner(System.in);

System.out.print("Nhập email: ");
String email = console.nextLine();

System.out.print("Nhập mật khẩu: ");
String password = console.nextLine();

// So sánh email không phân biệt hoa thường, còn mật khẩu thì phân biệt
if (email.equalsIgnoreCase(registeredEmail) && password.equals(registeredPassword))
{
    System.out.println("Chào mừng!");
}
else
{
    System.out.println("Email hoặc mật khẩu không đúng.");
}

Ghi chú: đối với email dùng equalsIgnoreCase(), còn đối với mật khẩu — dùng nghiêm ngặt equals(). Không được dùng toán tử == cho chuỗi — nó so sánh tham chiếu.

10. Các lỗi thường gặp khi so sánh chuỗi

Lỗi №1: So sánh chuỗi bằng == thay vì equals()
Toán tử == so sánh tham chiếu chứ không phải nội dung, vì vậy kết quả có thể bất ngờ.

Lỗi №2: Gọi equals() trên đối tượng có thể là null
Hãy gọi phương thức trên đối tượng chắc chắn không-null hoặc dùng Objects.equals(a, b).

Lỗi №3: Bỏ qua phân biệt hoa thường khi điều đó quan trọng
Ví dụ, mật khẩu phải được so sánh có phân biệt hoa thường. Hãy làm rõ yêu cầu.

Lỗi №4: So sánh chuỗi với đối tượng kiểu khác
"123"123 — không giống nhau. equals() không tự động chuyển kiểu.

Lỗi №5: Sắp xếp chuỗi có lẫn hoa và thường
Chữ hoa đứng trước chữ thường. Để sắp xếp không phân biệt hoa thường, dùng Arrays.sort(array, String.CASE_INSENSITIVE_ORDER).

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION