ภาพรวม
บทความนี้แนะนำการใช้ TreeSet ใน Android/Java ซึ่งเป็นการ implement ของ SortedSet ใช้ Red-Black Tree เก็บข้อมูล ไม่ซ้ำกัน (Unique) และ เรียงลำดับอัตโนมัติ (Natural Ordering)
Layout (activity_main.xml)
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter Name" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save" />
<Button
android:id="@+id/refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refresh" />
</LinearLayout>
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private EditText nameEditText;
private ListView listView;
private ArrayAdapter arrayAdapter;
private ArrayList arrayList;
private TreeSet treeSet; // ใช้ TreeSet โดยตรง
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nameEditText = findViewById(R.id.name);
listView = findViewById(R.id.listView);
arrayList = new ArrayList<>();
treeSet = new TreeSet<>(); // เรียง A-Z อัตโนมัติ
// Refresh Button
findViewById(R.id.refresh).setOnClickListener(v -> {
if (arrayAdapter != null) {
arrayAdapter.notifyDataSetChanged();
}
});
// Save Button
findViewById(R.id.save).setOnClickListener(v -> {
String input = nameEditText.getText().toString().trim();
if (!input.isEmpty()) {
// TreeSet ไม่อนุญาตค่าซ้ำ และเรียงลำดับอัตโนมัติ
treeSet.add(input);
// Sync ไป ArrayList สำหรับ Adapter
arrayList.clear();
arrayList.addAll(treeSet);
if (arrayAdapter == null) {
arrayAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, arrayList);
listView.setAdapter(arrayAdapter);
} else {
arrayAdapter.notifyDataSetChanged();
}
nameEditText.setText("");
Toast.makeText(this, "Inserted: " + input, Toast.LENGTH_SHORT).show();
} else {
nameEditText.setError("Enter NAME");
}
});
}
}
คุณสมบัติ TreeSet
| คุณสมบัติ | รายละเอียด |
| Unique Elements | ไม่รับค่าซ้ำ (ใช้ equals()/compareTo() ตรวจสอบ) |
| Sorted | เรียงตาม Natural Order (String: A-Z, Number: น้อย-มาก) |
| Null | ไม่รองรับ null (โยน NullPointerException) |
| Thread Safety | Not thread-safe (ใช้ Collections.synchronizedSortedSet() ถ้าต้องการ) |
| Performance | add/remove/contains: O(log n) |
TreeSet vs HashSet vs LinkedHashSet
| Set Implementation | Ordering | Duplicates | Null | Performance |
| HashSet | ไม่มีลำดับ | ไม่รับ | รองรับ 1 ค่า | O(1) |
| LinkedHashSet | ลำดับการ Insert | ไม่รับ | รองรับ 1 ค่า | O(1) |
| TreeSet | เรียงลำดับ (Sorted) | ไม่รับ | ไม่รองรับ | O(log n) |
Custom Comparator (เรียงแบบกำหนดเอง)
// เรียงจาก Z-A
TreeSet descSet = new TreeSet<>(Comparator.reverseOrder());
// เรียงตามความยาวสตริง
TreeSet lengthSet = new TreeSet<>((a, b) -> {
int lenCompare = Integer.compare(a.length(), b.length());
return lenCompare != 0 ? lenCompare : a.compareTo(b);
});
// Case-insensitive
TreeSet ciSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
เมธอดที่ใช้บ่อย
first() / last() - ค่าแรก/สุดท้าย
headSet(E) - subset น้อยกว่า E
tailSet(E) - subset มากกว่าหรือเท่า E
subSet(E1, E2) - subset ในช่วง
lower(E) / higher(E) - ค่าก่อน/หลัง E
floor(E) / ceiling(E) - ≤ E / ≥ E
pollFirst() / pollLast() - ดึงและลบค่าแรก/สุดท้าย