Saya bertanya-tanya mengapa java.util.ArrayList
memungkinkan untuk menambahkan null
. Apakah ada kasus di mana saya ingin menambahkan null
ke ArrayList
?
Saya mengajukan pertanyaan ini karena dalam sebuah proyek kami memiliki bug di mana beberapa kode ditambahkan null
ke ArrayList
dan sulit untuk menemukan di mana bug itu. Jelas sebuah NullPointerException
dilemparkan tetapi tidak sampai kode lain mencoba mengakses elemen. Masalahnya adalah bagaimana menemukan kode yang menambahkan null
objek. Akan lebih mudah jika ArrayList
melemparkan pengecualian dalam kode tempat elemen ditambahkan.
java
api-design
collections
Alfredo Osorio
sumber
sumber
null
di sebagian besar koleksi mereka).null
adalah cara default untuk mewakili data yang hilang di Jawa, apakah Anda suka atau tidak. Bahkan banyak orang tidak menyukainya dan menjadikannya argumen untuk hal-hal gaya pemrograman fungsional. Jawaban yang paling banyak dipilih tidak masuk akal / tidak menangkap esensi masalah.null
itu. "Hilang" hanyalah salah satu dari beberapa interpretasi potensialnull
. Interpretasi lain yang valid dapat berupa "Tidak Diketahui," "Tidak Berlaku," atau "Tidak diinisialisasi." Apa yangnull
diwakili tergantung pada aplikasi. Seperti yang akan dikatakan komunitas Python, "Di hadapan ambiguitas, tolak godaan untuk menebak." Menolak memegang nol dalam wadah yang benar-benar mampu melakukannya hanya akan menjadi - sebuah tebakan.Jawaban:
Keputusan desain ini muncul sebagian besar didorong oleh penamaan.
Nama ArrayList menyarankan kepada pembaca fungsi yang mirip dengan array - dan wajar bagi para desainer Java Collections Framework untuk berharap bahwa sebagian besar pengguna API akan bergantung pada fungsinya yang mirip dengan array.
Ini khususnya, melibatkan perawatan elemen-elemen nol. Pengguna API mengetahui bahwa di bawah ini berfungsi OK:
akan sangat terkejut mengetahui apakah kode yang sama untuk ArrayList akan membuang NPE:
Penalaran seperti di atas disajikan dalam JCF tutorial menekankan poin yang menunjukkan kesamaan antara ArrayList dan array sederhana:
Jika Anda ingin implementasi Daftar yang melarang nol, lebih baik disebut seperti
NonNullableArrayList
atau sesuatu seperti itu, untuk menghindari pengguna API yang membingungkan.Catatan tambahan ada diskusi tambahan dalam komentar di bawah ini, bersama dengan pertimbangan tambahan yang mendukung alasan yang disebutkan di sini.
sumber
LinkedList
juga mendukungnull
entri daftar.null
entri berguna dalam banyak kasus.Null mungkin nilai yang valid untuk elemen daftar. Katakanlah daftar Anda mengandung elemen yang mewakili beberapa data opsional tentang daftar pengguna dan disimpan dalam urutan yang sama dengan pengguna. Jika data tambahan diisi maka daftar Anda akan berisi data tambahan jika tidak, slot yang terkait dengan pengguna akan menjadi nol. (Saya yakin ada contoh yang lebih baik, tetapi Anda mendapatkan idenya)
jika Anda tidak ingin memperbolehkan nulls ditambahkan maka Anda bisa membungkus daftar array dengan pembungkus Anda sendiri yang dilemparkan ketika nol ditambahkan.
sumber
ArrayList
memungkinkan null dengan desain. Disengaja. Dari javadoc :Jawaban untuk "mengapa" adalah bahwa jika bukan ArrayList tidak akan dapat digunakan dalam kasus-kasus di mana perlu untuk memasukkan
null
dalam daftar. Sebaliknya, Anda dapat mencegah ArrayList berisi null dengan menguji nilai sebelum menambahkannya atau menggunakan pembungkus yang mencegah hal ini terjadi.Jelas, kasus mana pun
null
memiliki makna yang berbeda. Misalnya itu mungkin berarti bahwa nilai pada posisi tertentu dalam daftar belum diinisialisasi atau disediakan.Anda bisa dengan mudah menerapkan perilaku itu dengan membuat kelas pembungkus. Namun, ini bukan perilaku yang paling dibutuhkan oleh programmer / aplikasi.
sumber
Apakah ada kasus di mana saya ingin menambahkan null ke ArrayList?
Tentu, bagaimana dengan pra-alokasi? Anda menginginkan beberapa
ArrayList
hal yang belum dapat Anda buat karena Anda tidak memiliki cukup info. Hanya karena Anda tidak dapat memikirkan alasan mengapa seseorang mungkin ingin melakukan sesuatu tidak menjadikannya ide yang buruk. Terserah. (Sekarang, saya yakin seseorang akan datang dan mengatakan Anda seharusnya memiliki benda kosong yang memenuhi beberapa pola yang mereka baca di beberapa blog yang tidak jelas dan bahwa programmer harus benar-benar dapat menulis program tanpa menggunakanif
pernyataan, bla bla.)Jika kalian memiliki kontrak yang tidak boleh ada
null
dalam wadah maka terserah Anda untuk memastikan bahwa kontrak ditegakkan, mungkin paling tepat dengan menegaskan. Mungkin akan membawa Anda maksimal 10 baris kode. Java membuatnya sangat mudah bagi Anda untuk melakukan hal semacam ini. JDK tidak dapat membaca pikiran Anda.sumber
ensureCapacity(int minCapacity)
metode danArrayList(int initialCapacity)
konstruktor.null
dalam entri yang telah dialokasikan sebelumnya (tetapi belum digunakan )ArrayList
; tetapi kita dapat membiarkannya tetapiensureCapacity
tidak mengizinkan fungsi lain sepertiset
melakukannya. Alasan yang diberikan di tempat lain tampak lebih kuat.set
suatu barang dengan nilai berapa pun yang dapat dikembalikanget
. Sekalipun upaya normal terhadapget
item yang telah dialokasikan ruang tetapi tidak pernah ditulis harus membuang pengecualian daripada kembalinull
, masih akan berguna untuk memiliki sepasang metode yang akan memungkinkanlist1.setOrEraseIfNull(index, list2.getOrReturnNull(index))
daripada membutuhkanif (list2.valueSet(index)) list1.set(index, list2.get(index)); else list1.unset(index);
Ini sepertinya lebih merupakan pertanyaan filosofis (perangkat lunak) di sini.
ArrayList
sebagai kelas utilitas dirancang untuk membantu dalam konteks yang luas dari kasus penggunaan yang mungkin.Bertentangan dengan klaim tersembunyi Anda bahwa menerima nol sebagai nilai yang valid harus dihilangkan, ada banyak contoh di mana nilai nol itu sah menurut hukum.
Alasan paling penting adalah bahwa
null
inido not know
setara dengan semua jenis referensi, termasuk jenis kerangka kerja. Ini menyiratkan bahwa null tidak dapat diganti dalam hal apa pun dengan versinothing
nilai yang lebih lancar .Jadi, katakanlah Anda menyimpan Integer 1, 3, 7 di daftar array Anda pada indeks yang sesuai: Karena beberapa perhitungan, Anda ingin mendapatkan elemen pada indeks 5, jadi yang harus dikembalikan oleh array Anda adalah: "tidak ada nilai yang disimpan". Ini dapat dicapai melalui pengembalian null atau NullObject . Dalam kebanyakan kasus mengembalikan nilai null bawaan cukup ekspresif. Setelah memanggil metode yang dapat mengembalikan nol dan menggunakan nilai baliknya, cek nilai yang dikembalikan terhadap nol cukup umum dalam kode modern.
sumber
Pernyataan
valid dan bermanfaat (saya pikir saya tidak perlu menjelaskan alasannya). Juga bermanfaat untuk memiliki koleksi file, beberapa di antaranya mungkin nol.
Kegunaan koleksi yang mungkin berisi objek nol hasil langsung dari kegunaan objek yang mungkin nol. Ini sangat sederhana.
sumber
Lebih mudah menerima semuanya, daripada menjadi membatasi dan kemudian mencoba membuka desain Anda setelah fakta.
Sebagai contoh, bagaimana jika mereka oracle / sun hanya menyediakan NonNullableArrayList, tetapi Anda ingin dapat menambahkan Null ke daftar Anda. Bagaimana Anda melakukannya? Anda mungkin harus membuat objek yang sama sekali berbeda, Anda tidak dapat menggunakan memperpanjang NonNullableArrayList. Alih-alih jika Anda memiliki ArrayList yang mengambil semuanya, Anda dapat dengan mudah memperluasnya, dan mengganti add, di mana ia tidak menerima nilai nol.
sumber
Kegunaan nol?
Sangat banyak ketika Anda pergi dengan Daftar Daftar untuk memodelkan pelat kehidupan nyata 2D dengan posisi yang berbeda. Setengah dari posisi itu bisa kosong (dalam koordinat acak) sementara yang diisi tidak mewakili int atau String sederhana tetapi diwakili oleh objek yang kompleks. Jika Anda ingin menyimpan informasi posisi, Anda perlu mengisi tempat kosong dengan nol sehingga list.get (x) .get (y)tidak menyebabkan kejutan yang tidak menyenangkan. Untuk melawan pengecualian nol Anda dapat memeriksa null (sangat populer) atau Anda dapat menggunakan Opsional (yang menurut saya berguna dalam kasus ini). Alternatifnya adalah mengisi tempat-tempat kosong dengan benda-benda "sampah" yang dapat menyebabkan semua jenis kekacauan di jalan. Jika cek nol Anda gagal atau dilupakan di suatu tempat, Java akan memberi tahu Anda. Di sisi lain objek placeholder "sampah" yang tidak diperiksa dengan benar dapat melewati tanpa disadari.
sumber