Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีลบพื้นที่ว่างใน ListView ArrayList บน Android

การจัดการพื้นที่ว่างและข้อมูลซ้ำใน ListView ด้วย ArrayList และ HashSet

ตัวอย่างนี้สาธิตวิธีป้องกันการแสดงข้อมูลซ้ำและจัดการความจุของ ArrayList ให้เหมาะสม ก่อนแสดงใน ListView โดยใช้ HashSet กรองข้อมูลซ้ำ และ trimToSize() ลดความจุให้เท่ากับจำนวนข้อมูลจริง

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

สร้างโปรเจกต์ Android ใหม่ใน Android Studio

ขั้นตอนที่ 2: ออกแบบ Layout (res/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"
    tools:context=".MainActivity"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/etName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="ป้อนชื่อ" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:orientation="horizontal">
        <Button android:id="@+id/btnSave" android:text="บันทึก" android:layout_width="wrap_content" android:layout_height="wrap_content" />
        <Button android:id="@+id/btnRefresh" android:text="รีเฟรช" android:layout_width="wrap_content" android:layout_height="wrap_content" />
    </LinearLayout>

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp">
    </ListView>
</LinearLayout>

ขั้นตอนที่ 3: MainActivity.java

package com.example.myapplication;

import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class MainActivity extends AppCompatActivity {
    private EditText etName;
    private ListView listView;
    private ArrayAdapter<String> adapter;
    private ArrayList<String> arrayList;
    private Set<String> uniqueSet = new HashSet<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        arrayList = new ArrayList<>();
        // กำหนดความจุเริ่มต้น (optional) ช่วยลดการ resize array ภายใน
        arrayList.ensureCapacity(20);

        etName = findViewById(R.id.etName);
        listView = findViewById(R.id.listView);

        findViewById(R.id.btnRefresh).setOnClickListener(v -> {
            if (adapter != null) {
                adapter.notifyDataSetChanged();
                listView.invalidateViews();
                listView.refreshDrawableState();
            }
        });

        findViewById(R.id.btnSave).setOnClickListener(v -> {
            String input = etName.getText().toString().trim();
            if (!input.isEmpty()) {
                // เพิ่มลง Set เพื่อกรองข้อมูลซ้ำอัตโนมัติ
                uniqueSet.add(input);

                // ล้าง ArrayList และเพิ่มข้อมูลจาก Set ใหม่
                arrayList.clear();
                arrayList.addAll(uniqueSet);

                // เรียงลำดับ A-Z
                Collections.sort(arrayList);

                // สำคัญ: ลดความจุ internal array ให้เท่ากับ size จริง
                // ช่วยประหยัดหน่วยความจำเมื่อข้อมูลน้อยกว่าความจุที่จองไว้
                arrayList.trimToSize();

                // สร้าง Adapter ใหม่และเซ็ตให้ ListView
                adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, arrayList);
                listView.setAdapter(adapter);

                Toast.makeText(this, "บันทึกสำเร็จ (จำนวน: " + arrayList.size() + ")", Toast.LENGTH_SHORT).show();
            } else {
                etName.setError("กรุณาป้อนชื่อ");
            }
        });
    }
}

คำอธิบายเทคนิคสำคัญ

1. HashSet ป้องกันข้อมูลซ้ำ

Set<String> uniqueSet = new HashSet<>();
uniqueSet.add(input); // เพิ่มข้อมูล - ถ้าซ้ำจะไม่เพิ่มเข้าไป
  • HashSet ไม่อนุญาตให้มีค่าซ้ำ (ใช้ equals() และ hashCode() ตรวจสอบ)
  • เพิ่ม/ค้นหา/ลบ ทำงานได้ใน O(1) 平均
  • ไม่รักษาลำดับการเพิ่ม (ใช้ LinkedHashSet ถ้าต้องการรักษาลำดับ)

2. trimToSize() ลดความจุ ArrayList

arrayList.trimToSize();
  • ArrayList มี size (จำนวนข้อมูลจริง) และ capacity (ขนาด array ภายใน)
  • เมื่อเพิ่มข้อมูลมากแล้วลบออก capacity จะไม่ลดลงอัตโนมัติ
  • trimToSize() ทำให้ capacity = size ปัจจุบัน ประหยัดหน่วยความจำ
  • เหมาะสำหรับ ListView ที่ข้อมูลเปลี่ยนแปลงบ่อย

3. ensureCapacity() กำหนดความจุเริ่มต้น

arrayList.ensureCapacity(20);
  • จองพื้นที่ไว้ล่วงหน้า ลดจำนวนครั้งที่ต้อง resize array (copy array ใหม่)
  • เพิ่มประสิทธิภาพเมื่อทราบจำนวนข้อมูลโดยประมาณ

ตัวอย่างการทำงาน

  1. ป้อน: "Sairam" → ListView แสดง: Sairam
  2. ป้อน: "A" → ListView แสดง: A, Sairam (เรียง A-Z)
  3. ป้อน: "Sairam" ซ้ำ → ไม่เพิ่ม เพราะ HashSet กรองซ้ำ
  4. ป้อน: "B" → ListView แสดง: A, B, Sairam

ข้อดีของแนวทางนี้

  • ไม่มีข้อมูลซ้ำใน ListView
  • ข้อมูลเรียงลำดับอัตโนมัติ
  • หน่วยความจำถูกจัดการอย่างมีประสิทธิภาพ
  • UI ตอบสนองเร็ว ไม่มีการ render item ซ้ำ