Giới thiệu
Hướng dẫn này trình bày cách sử dụng TreeSet trong Android để lưu trữ dữ liệu không trùng lặp và tự động sắp xếp theo thứ tự tự nhiên (alphabetical cho String).
Các bước thực hiện
Bước 1: Tạo dự án mới
Tạo dự án Android Studio: File → New Project.
Bước 2: Layout activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MainActivity">
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Nhập tên"
android:inputType="text" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="16dp">
<Button
android:id="@+id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Lưu" />
<Button
android:id="@+id/refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Làm mới"
android:layout_marginStart="8dp" />
</LinearLayout>
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginTop="16dp" />
</LinearLayout>
Bước 3: MainActivity.java
package com.example.myapplication;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Set;
import java.util.TreeSet;
public class MainActivity extends AppCompatActivity {
EditText nameEditText;
ArrayAdapter arrayAdapter;
ArrayList arrayList;
Set treeSet = new TreeSet<>();
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arrayList = new ArrayList<>();
nameEditText = findViewById(R.id.name);
listView = findViewById(R.id.listView);
// Khởi tạo adapter
arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, arrayList);
listView.setAdapter(arrayAdapter);
// Nút Làm mới
findViewById(R.id.refresh).setOnClickListener(v -> {
arrayAdapter.notifyDataSetChanged();
listView.invalidateViews();
});
// Nút Lưu
findViewById(R.id.save).setOnClickListener(v -> {
String inputName = nameEditText.getText().toString().trim();
if (!inputName.isEmpty()) {
// TreeSet tự động loại bỏ trùng lặp và sắp xếp
treeSet.add(inputName);
// Cập nhật ArrayList từ TreeSet
arrayList.clear();
arrayList.addAll(treeSet);
// Cập nhật ListView
arrayAdapter.notifyDataSetChanged();
Toast.makeText(this, "Đã thêm: " + inputName, Toast.LENGTH_SHORT).show();
nameEditText.setText("");
} else {
nameEditText.setError("Vui lòng nhập tên");
}
});
}
}
Đặc điểm của TreeSet
| Đặc điểm | Mô tả |
|---|---|
| Không trùng lặp | Tự động loại bỏ phần tử duplicate (dựa trên equals/compareTo) |
| Tự động sắp xếp | Thứ tự tự nhiên (Natural Ordering) - String: A-Z, a-z, số |
| Hiệu suất | O(log n) cho add, remove, contains (dựa trên Red-Black Tree) |
| Null | Không cho phép null element (ném NullPointerException) |
| Luồng (Thread) | Không thread-safe (cần Collections.synchronizedSet nếu đa luồng) |
TreeSet vs HashSet vs LinkedHashSet
| Collection | Sắp xếp | Trùng lặp | Hiệu suất | Sử dụng khi |
|---|---|---|---|---|
| TreeSet | Tự động (A-Z) | Không | O(log n) | Cần dữ liệu đã sắp xếp |
| HashSet | Không đảm bảo | Không | O(1) | Cần hiệu suất cao, không quan tâm thứ tự |
| LinkedHashSet | Thứ tự thêm | Không | O(1) | Cần giữ thứ tự insert, không trùng |
TreeSet với đối tượng tùy chỉnh (Custom Object)
// Cần implements Comparable hoặc cung cấp Comparator
public class Student implements Comparable {
String name;
int age;
@Override
public int compareTo(Student other) {
return this.name.compareTo(other.name); // Sắp xếp theo tên
}
}
// Hoặc dùng Comparator
Set students = new TreeSet<>((s1, s2) -> s1.age - s2.age); // Sắp xếp theo tuổi
Lưu ý quan trọng
- TreeSet sử dụng
compareTo()(hoặc Comparator) để kiểm tra trùng lặp, KHÔNG dùngequals(). - Nếu
compareTo()trả về 0 cho 2 object khác nhau → TreeSet coi là trùng lặp và loại bỏ. - Luôn implement
Comparableconsistent vớiequals()để tránh bug khó tìm. - Trong Android, TreeSet nằm trong
java.util, không cần thư viện thêm.