Giới thiệu
Bài viết minh họa cách dùng phương thức String.compareTo() để so sánh hai chuỗi theo thứ tự từ điển (lexicographical order) trong Android. Trả về số âm, 0, hoặc dương.
Các bước thực hiện
Bước 1: Tạo project mới
Android Studio → File → New Project → Empty Activity.
Bước 2: Giao diện (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="16dp">
<EditText
android:id="@+id/etInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Nhập chuỗi để so sánh với 'sairam'"
android:inputType="text" />
<Button
android:id="@+id/btnCompare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="So sánh" />
<TextView
android:id="@+id/tvResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
Bước 3: Logic (MainActivity.kt)
package com.example.compareto
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnCompare.setOnClickListener {
val input = etInput.text.toString()
if (input.isEmpty()) {
etInput.error = "Vui lòng nhập chuỗi"
return@setOnClickListener
}
val target = "sairam"
val result = input.compareTo(target)
val message = when {
result < 0 -> "\"$input\" < \"$target\" (trước trong từ điển), diff = $result"
result > 0 -> "\"$input\" > \"$target\" (sau trong từ điển), diff = $result"
else -> "\"$input\" == \"$target\" (bằng nhau)"
}
tvResult.text = "compareTo result: $result\n$message"
Toast.makeText(this, message, Toast.LENGTH_LONG).show()
}
}
}
Giải thích compareTo()
- So sánh **lexicographically** (theo thứ tự Unicode code point).
- Trả về:
< 0: Chuỗi này < target (xuất hiện trước trong từ điển).= 0: Hai chuỗi bằng nhau.> 0: Chuỗi này > target (xuất hiện sau trong từ điển).
- Giá trị tuyệt đối không phải độ dài chênh lệch, mà là chênh lệch code point tại vị trí khác nhau đầu tiên.
Ví dụ minh họa
| Chuỗi A | Chuỗi B | A.compareTo(B) | Giải thích |
|---|---|---|---|
| "apple" | "banana" | -1 ('a' - 'b' = -1) | 'a' (97) < 'b' (98) |
| "sairam" | "sairam" | 0 | Giống hệt |
| "zebra" | "apple" | 25 ('z' - 'a' = 122-97) | 'z' > 'a' |
| "abc" | "abcd" | -1 (độ dài chênh 1) | "abc" ngắn hơn, là prefix |
| "Abc" | "abc" | -32 ('A'=65, 'a'=97) | Hoa < Thường (Unicode) |
Biến thể: compareToIgnoreCase()
// Không phân biệt hoa/thường
val result = input.compareTo("sairam", ignoreCase = true) // Kotlin extension
// Java
int result = input.compareToIgnoreCase("sairam");
Lưu ý
compareTodùng cho **sắp xếp (sorting)**, không phải kiểm tra bằng nhau (dùngequals()).- Phân biệt chữ hoa/thường: 'A' (65) < 'a' (97).
- Với tiếng Việt có dấu: so sánh theo Unicode code point, không theo thứ tự bảng chữ cái tiếng Việt. Cần Collator cho locale-aware sorting.
- Null safety:
"abc".compareTo(null)ném NPE. Kotlin:input?.compareTo(target).
Sắp xếp danh sách chuỗi
val list = listOf("banana", "apple", "cherry", "date")
val sorted = list.sorted() // Dùng compareTo tự nhiên
// ["apple", "banana", "cherry", "date"]
val sortedDesc = list.sortedDescending()
// ["date", "cherry", "banana", "apple"]
// Locale-aware (tiếng Việt)
val collator = java.text.Collator.getInstance(java.util.Locale("vi", "VN"))
val sortedVi = list.sortedWith(compareBy { collator.getCollationKey(it) })