Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách kiểm tra sự tồn tại của phần tử trong ListView Android

Giới thiệu

Kiểm tra xem một giá trị đã có trong ListView hay chưa trước khi thêm mới. Sử dụng ArrayList.contains() (O(n)) hoặc HashSet (O(1)) để tối ưu. Tránh trùng lặp dữ liệu.

Triển khai

Bước 1: Tạo dự án

Android Studio → New Project → Empty Activity.

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/edit_query"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Nhập tên thiết bị (Android, iPhone...)" />

    <Button
        android:id="@+id/buttonPanel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Thêm / Kiểm tra" />

    <ListView
        android:id="@+id/list"
        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.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class MainActivity extends AppCompatActivity {
    ListView listView;
    EditText editQuery;
    Button btnCheck;
    
    // Dữ liệu gốc
    String[] mobileArray = {"Android", "iPhone", "WindowsMobile", "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X"};
    
    // Dùng ArrayList cho Adapter
    ArrayList<String> arrayList;
    // Dùng HashSet cho kiểm tra O(1)
    Set<String> existingSet;
    ArrayAdapter<String> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        editQuery = findViewById(R.id.edit_query);
        btnCheck = findViewById(R.id.buttonPanel);
        listView = findViewById(R.id.list);
        
        // Khởi tạo dữ liệu
        arrayList = new ArrayList<>(Arrays.asList(mobileArray));
        existingSet = new HashSet<>(arrayList); // Sync với arrayList
        
        // Adapter
        adapter = new ArrayAdapter<>(this, 
                android.R.layout.simple_list_item_1, arrayList);
        listView.setAdapter(adapter);

        btnCheck.setOnClickListener(v -> {
            String input = editQuery.getText().toString().trim();
            if (input.isEmpty()) {
                Toast.makeText(this, "Vui lòng nhập giá trị", Toast.LENGTH_SHORT).show();
                return;
            }
            
            // KIỂM TRA TỒN TẠI - O(1) với HashSet
            if (existingSet.contains(input)) {
                Toast.makeText(this, "⚠ '" + input + "' đã có trong danh sách", Toast.LENGTH_LONG).show();
            } else {
                // Thêm mới
                arrayList.add(input);
                existingSet.add(input); // Đồng bộ set
                adapter.notifyDataSetChanged(); // Cập nhật ListView
                Toast.makeText(this, "✓ Đã thêm '" + input + "'", Toast.LENGTH_SHORT).show();
                editQuery.setText(""); // Clear input
            }
        });
    }
}

So sánh phương pháp kiểm tra

Phương phápĐộ phức tạpCodePhù hợp
ArrayList.contains()O(n)list.contains(item)List nhỏ (<100), ít thao tác
HashSet.contains()O(1)set.contains(item)List lớn, kiểm tra thường xuyên
Adapter.getPosition()O(n)adapter.getPosition(item) >= 0Chỉ khi không có access đến data source

Pattern đồng bộ List + Set

class SyncedList<T> {
    private final List<T> list = new ArrayList<>();
    private final Set<T> set = new HashSet<>();
    
    public boolean add(T item) {
        if (set.contains(item)) return false;
        list.add(item);
        set.add(item);
        return true;
    }
    
    public boolean remove(T item) {
        boolean removed = list.remove(item);
        if (removed) set.remove(item);
        return removed;
    }
    
    public List<T> getList() { return list; }
    public boolean contains(T item) { return set.contains(item); }
}

Kết quả

  1. Khởi động: ListView hiển thị 8 thiết bị có sẵn
  2. Nhập "Android" → Toast "⚠ 'Android' đã có trong danh sách"
  3. Nhập "Samsung" → Thêm vào cuối list, Toast "✓ Đã thêm 'Samsung'"

Mở rộng: Tìm kiếm real-time (Filter)

editQuery.addTextChangedListener(new TextWatcher() {
    @Override public void onTextChanged(CharSequence s, int start, int before, int count) {
        adapter.getFilter().filter(s); // Tự động lọc ListView
    }
    @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
    @Override public void afterTextChanged(Editable s) {}
});
Lưu ý: ArrayAdapter có sẵn Filter cho tìm kiếm đơn giản. Với dữ liệu phức tạp/custom object, cần implement Filterable interface.