Giới thiệu
Hướng dẫn này trình bày cách sử dụng interface SortedSet trong Android. SortedSet là interface mở rộng từ Set, đảm bảo các phần tử được sắp xếp theo thứ tự tự nhiên hoặc theo Comparator tùy chỉnh. TreeSet là implementation phổ biến nhất của SortedSet.
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.SortedSet;
import java.util.TreeSet;
public class MainActivity extends AppCompatActivity {
EditText nameEditText;
ArrayAdapter arrayAdapter;
ArrayList arrayList;
// Khai báo kiểu SortedSet (interface) thay vì TreeSet (implementation)
SortedSet sortedSet = 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);
arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, arrayList);
listView.setAdapter(arrayAdapter);
findViewById(R.id.refresh).setOnClickListener(v -> {
arrayAdapter.notifyDataSetChanged();
listView.invalidateViews();
});
findViewById(R.id.save).setOnClickListener(v -> {
String inputName = nameEditText.getText().toString().trim();
if (!inputName.isEmpty()) {
sortedSet.add(inputName);
arrayList.clear();
arrayList.addAll(sortedSet);
arrayAdapter.notifyDataSetChanged();
Toast.makeText(this, "Đã thêm: " + inputName, Toast.LENGTH_SHORT).show();
nameEditText.setText("");
} else {
nameEditText.setError("Vui lòng nhập tên");
}
});
}
}
SortedSet Interface - Các phương thức đặc biệt
Khác với Set thông thường, SortedSet cung cấp các phương thức truy xuất theo thứ tự:
| Phương thức | Mô tả |
|---|---|
| first() | Trả về phần tử nhỏ nhất (đầu tiên) |
| last() | Trả về phần tử lớn nhất (cuối cùng) |
| headSet(E toElement) | Trả về subset các phần tử < toElement |
| tailSet(E fromElement) | Trả về subset các phần tử >= fromElement |
| subSet(E from, E to) | Trả về subset trong khoảng [from, to) |
| comparator() | Trả về Comparator đang dùng (null = natural ordering) |
Ví dụ sử dụng các phương thức SortedSet
SortedSet names = new TreeSet<>();
names.addAll(Arrays.asList("D", "A", "E", "B", "C"));
System.out.println("First: " + names.first()); // A
System.out.println("Last: " + names.last()); // E
System.out.println("HeadSet C: " + names.headSet("C")); // [A, B]
System.out.println("TailSet C: " + names.tailSet("C")); // [C, D, E]
System.out.println("SubSet B-D: " + names.subSet("B", "D")); // [B, C]
SortedSet vs NavigableSet
NavigableSet extends SortedSet thêm các phương thức điều hướng:
lower(E e)- phần tử lớn nhất < ehigher(E e)- phần tử nhỏ nhất > efloor(E e)- phần tử lớn nhất <= eceiling(E e)- phần tử nhỏ nhất >= epollFirst() / pollLast()- lấy và xóa phần tử đầu/cuốidescendingSet()- view ngược thứ tự
TreeSet implement cả NavigableSet, nên có thể ép kiểu: NavigableSet
Tại sao khai báo kiểu SortedSet thay vì TreeSet?
// Tốt: Lập trình hướng interface (Interface-based programming)
SortedSet set = new TreeSet<>();
// Có thể thay implementation dễ dàng:
// SortedSet set = new ConcurrentSkipListSet<>(); // Thread-safe
// SortedSet set = new TreeSet<>(customComparator); // Custom sort
- Giảm sự phụ thuộc vào implementation cụ thể.
- Tuân thủ nguyên lý SOLID (Dependency Inversion Principle).
Lưu ý
- SortedSet không cho phép phần tử null (ném NPE).
- Các view trả về (headSet, tailSet, subSet) là backed by original set - thay đổi view ảnh hưởng gốc và ngược lại.
- Iterator duyệt theo thứ tự tăng dần.