SparseArray
dapat digunakan untuk mengganti HashMap
ketika kuncinya adalah tipe primitif. Ada beberapa varian untuk tipe kunci / nilai yang berbeda, meskipun tidak semuanya tersedia untuk umum.
Manfaatnya adalah:
- Bebas alokasi
- Tidak ada tinju
Kekurangan:
- Umumnya lebih lambat, tidak diindikasikan untuk koleksi besar
- Mereka tidak akan bekerja di proyek non-Android
HashMap
dapat diganti dengan yang berikut ini:
SparseArray <Integer, Object>
SparseBooleanArray <Integer, Boolean>
SparseIntArray <Integer, Integer>
SparseLongArray <Integer, Long>
LongSparseArray <Long, Object>
LongSparseLongArray <Long, Long> //this is not a public class
//but can be copied from Android source code
Dalam hal memori, berikut adalah contoh SparseIntArray
vs HashMap<Integer, Integer>
untuk 1000 elemen:
SparseIntArray
:
class SparseIntArray {
int[] keys;
int[] values;
int size;
}
Kelas = 12 + 3 * 4 = 24 byte
Array = 20 + 1000 * 4 = 4024 byte
Total = 8.072 byte
HashMap
:
class HashMap<K, V> {
Entry<K, V>[] table;
Entry<K, V> forNull;
int size;
int modCount;
int threshold;
Set<K> keys
Set<Entry<K, V>> entries;
Collection<V> values;
}
Kelas = 12 + 8 * 4 = 48 byte
Entri = 32 + 16 + 16 = 64 byte
Array = 20 + 1000 * 64 = 64024 byte
Total = 64.136 byte
Sumber: Android Memories oleh Romain Guy dari slide 90.
Angka-angka di atas adalah jumlah memori (dalam byte) yang dialokasikan pada heap oleh JVM. Mereka dapat bervariasi tergantung pada JVM spesifik yang digunakan.
The java.lang.instrument
paket berisi beberapa metode membantu untuk operasi canggih seperti memeriksa ukuran suatu objek dengan getObjectSize(Object objectToSize)
.
Info tambahan tersedia dari dokumentasi resmi Oracle .
Kelas = 12 byte + (n variabel instan) * 4 byte
Array = 20 byte + (n elemen) * (ukuran elemen)
Entri = 32 byte + (ukuran elemen 1) + (ukuran elemen 2)
Saya datang ke sini hanya ingin contoh cara menggunakan
SparseArray
. Ini adalah jawaban tambahan untuk itu.Buat SparseArray
Sebuah
SparseArray
peta bilangan bulat ke beberapaObject
, sehingga Anda dapat menggantiString
dalam contoh di atas dengan yang lainnyaObject
. Jika Anda memetakan bilangan bulat ke bilangan bulat, gunakanSparseIntArray
.Tambahkan atau perbarui item
Gunakan
put
(atauappend
) untuk menambahkan elemen ke array.Perhatikan bahwa
int
tombol tidak perlu berurutan. Ini juga dapat digunakan untuk mengubah nilai padaint
kunci tertentu .Hapus item
Gunakan
remove
(ataudelete
) untuk menghapus elemen dari array.The
int
parameter adalah kunci integer.Nilai pencarian untuk kunci int
Gunakan
get
untuk mendapatkan nilai untuk beberapa kunci integer.Anda dapat menggunakan
get(int key, E valueIfKeyNotFound)
jika Anda ingin menghindarinull
kunci yang hilang.Iterate atas item
Anda dapat menggunakan
keyAt
danvalueAt
beberapa indeks untuk mengulang koleksi karenaSparseArray
mempertahankan indeks terpisah berbeda dariint
tombol.Perhatikan bahwa kunci dipesan dalam nilai menaik, bukan dalam urutan yang ditambahkan.
sumber
Ini hanya peringatan dari dokumentasi ini tentang array yang jarang:
Ini
SparseArray
dibuat agar lebih efisien daripada menggunakan HashMap biasa, yang tidak memungkinkan banyak celah dalam array tidak seperti HashMap. Tidak ada yang perlu dikhawatirkan, Anda dapat menggunakan HashMap tradisional jika Anda ingin tidak khawatir tentang alokasi memori ke perangkat.sumber
SparseArray
mencegah integer kunci menjadi Auto box yang merupakan operasi dan kinerja biaya lainnya. alih-alih Peta itu akan autobox bilangan bulat primitif keInteger
Jarang array di Jawa adalah struktur data yang memetakan kunci untuk nilai. Gagasan yang sama dengan Peta, tetapi implementasinya berbeda:
Peta direpresentasikan secara internal sebagai array daftar, di mana setiap elemen dalam daftar ini adalah pasangan nilai kunci. Baik kunci maupun nilainya adalah instance objek.
Array jarang dibuat hanya dari dua array: array kunci (primitif) dan array nilai (objek). Mungkin ada kesenjangan dalam indeks array ini, karenanya istilah "jarang" array.
Minat utama SparseArray adalah menyimpan memori dengan menggunakan primitif alih-alih objek sebagai kuncinya.
sumber
Setelah beberapa googling saya mencoba menambahkan beberapa informasi ke yang sudah diposting:
Isaac Taylor membuat perbandingan kinerja untuk SparseArrays dan Hashmaps. Dia menyatakan itu
dan
Perbandingan di Edgblog menunjukkan bahwa SparseArray membutuhkan lebih sedikit memori daripada HashMap karena kunci yang lebih kecil (int vs Integer) dan fakta bahwa
Sebagai kesimpulan saya akan mengatakan bahwa perbedaannya bisa berarti jika Anda akan menyimpan banyak data di Peta Anda. Jika tidak, abaikan saja peringatan itu.
sumber
Ya itu benar. Tetapi ketika Anda hanya memiliki 10 atau 20 item, perbedaan kinerja seharusnya tidak signifikan.
Saya pikir paling sering kita hanya menggunakan
HashMap
untuk mencari nilai yang terkait dengan kunci sementaraSparseArray
sangat bagus dalam hal ini.Kode sumber SparseArray cukup sederhana dan mudah dipahami sehingga Anda hanya perlu sedikit upaya memindahkannya ke platform lain (melalui COPY & Paste sederhana).
Yang bisa saya katakan adalah, (untuk sebagian besar pengembang) siapa yang peduli?
Aspek penting lainnya
SparseArray
adalah bahwa ia hanya menggunakan array untuk menyimpan semua elemen saatHashMap
digunakanEntry
, jadiSparseArray
biaya memori yang signifikan lebih sedikit daripada aHashMap
, lihat inisumber
Sangat disayangkan bahwa kompiler mengeluarkan peringatan. Saya kira HashMap telah digunakan secara berlebihan untuk menyimpan item.
SparseArrays memiliki tempat mereka. Mengingat mereka menggunakan algoritma pencarian biner untuk menemukan nilai dalam array Anda harus mempertimbangkan apa yang Anda lakukan. Pencarian biner adalah O (log n) sedangkan pencarian hash adalah O (1). Ini tidak selalu berarti bahwa pencarian biner lebih lambat untuk set data yang diberikan. Namun, saat jumlah entri bertambah, kekuatan tabel hash mengambil alih. Karenanya komentar di mana jumlah entri yang rendah dapat sama dan mungkin lebih baik daripada menggunakan HashMap.
HashMap hanya sebagus hash dan juga dapat dipengaruhi oleh load factor (saya pikir di versi selanjutnya mereka mengabaikan load factor sehingga bisa dioptimalkan dengan lebih baik). Mereka juga menambahkan hash sekunder untuk memastikan hash baik. Juga alasan SparseArray bekerja sangat baik untuk entri yang relatif sedikit (<100).
Saya akan menyarankan bahwa jika Anda memerlukan tabel hash dan ingin penggunaan memori yang lebih baik untuk bilangan bulat primitif (tidak ada tinju otomatis), dll., Cobalah trove. ( http://trove.starlight-systems.com - lisensi LGPL). (Tidak ada afiliasi dengan trove, seperti perpustakaan mereka)
Dengan bangunan multi-dex yang disederhanakan, kami memiliki Anda, Anda bahkan tidak perlu mengemas kembali untuk apa yang Anda butuhkan. (Trove memiliki banyak kelas)
sumber