Giới thiệu
Bài viết minh họa cách dùng phương thức String.charAt(index) để lấy ký tự tại vị trí cụ thể (0-based index) từ chuỗi nhập trong EditText.
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 (ít nhất 6 ký tự)"
android:inputType="text" />
<Button
android:id="@+id/btnGetChar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Lấy ký tự thứ 5 (index 5)" />
<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.charatdemo
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)
btnGetChar.setOnClickListener {
val input = etInput.text.toString()
val targetIndex = 5 // Ký tự thứ 6 (index 5)
if (input.isEmpty()) {
etInput.error = "Vui lòng nhập chuỗi"
return@setOnClickListener
}
if (input.length <= targetIndex) {
Toast.makeText(this, "Chuỗi quá ngắn (cần ít nhất ${targetIndex + 1} ký tự)", Toast.LENGTH_LONG).show()
tvResult.text = "Chuỗi: '$input' (độ dài ${input.length}) - Không có index $targetIndex"
return@setOnClickListener
}
// Lấy ký tự tại index 5 (ký tự thứ 6)
val charAt5 = input[targetIndex] // Kotlin: input.get(targetIndex) hoặc input[targetIndex]
// Java: char ch = input.charAt(5);
tvResult.text = "Ký tự tại index $targetIndex: '$charAt5' (Unicode: U+${charAt5.toInt().toString(16).uppercase().padStart(4, '0')})"
Toast.makeText(this, "Index $targetIndex: '$charAt5'", Toast.LENGTH_LONG).show()
}
}
}
Giải thích charAt() / Indexing
- Index **0-based**: ký tự đầu tiên là index 0.
- Kotlin:
string[index](operator overload) hoặcstring.get(index). - Java:
string.charAt(index). - Trả về
Char(Kotlin) hoặcchar(Java). - Ném
IndexOutOfBoundsExceptionnếu index < 0 hoặc >= length.
Các phương thức liên quan
| Phương thức | Mô tả | Ví dụ |
|---|---|---|
charAt(index) / [index] |
Lấy ký tự tại index | "abc"[1] = 'b' |
get(index) |
Kotlin alias cho charAt | "abc".get(1) = 'b' |
first() |
Ký tự đầu (index 0) | "abc".first() = 'a' |
last() |
Ký tự cuối (index length-1) | "abc".last() = 'c' |
substring(start, end) |
Lấy chuỗi con | "abc".substring(1,3) = "bc" |
elementAtOrNull(index) |
An toàn, trả null nếu out of bounds | "ab".elementAtOrNull(5) = null |
Xử lý an toàn (Safe access)
// Kotlin safe access val char = input.getOrNull(5) ?: return // null nếu index không hợp lệ val char = input.elementAtOrNull(5) ?: ' ' // Java char ch = (input.length() > 5) ? input.charAt(5) : ' ';
Lưu ý Unicode
charAttrả về **UTF-16 code unit** (16-bit), không phải Unicode code point hoàn chỉnh.- Ký tự emoji, chữ Hán, tiếng Việt có dấu có thể chiếm 2 code units (surrogate pair).
- Dùng
codePointAt(index)để lấy code point thực (Int). - Kotlin:
string.codePointAt(index)hoặc iteratestring.toCharArray().
Ví dụ với Emoji
val emoji = "😀👍🎉" // Mỗi emoji = 2 UTF-16 code units
println(emoji.length) // 6 (3 emoji × 2)
println(emoji[0]) // '\uD83D' (high surrogate) - KHÔNG phải emoji hoàn chỉnh
println(emoji.codePointAt(0)) // 128512 (0x1F600) - ĐÚNG
// Duyệt đúng cách
emoji.forEach { println(it) } // Kotlin forEach hiểu code point
// Hoặc
for (i in 0 until emoji.length) {
val cp = emoji.codePointAt(i)
if (Character.isSupplementaryCodePoint(cp)) i++ // Bỏ qua low surrogate
}