Apa gunanya menambahkan kunci atau nilai null ke HashMap di Java?

91

HashMap memungkinkan satu kunci nol dan sejumlah nilai nol. Apa gunanya itu?

subhashis
sumber
11
"Mungkin masalahnya bukan karena tidak ada yang mengganggu kita, tapi kita yang mengganggunya."
bmargulies
3
Di Guava, koleksi google, banyak kelas tidak mengizinkan null dan alasan di baliknya adalah bahwa 95% kasus tidak memerlukan null dan mereka dapat mewakili bug, berpotensi sulit ditemukan.
stivlo
Anehnya, itu ConcurrentHashMaptidak mendukung kunci-null, sedangkan HashMaptidak.
codepleb
2
Hanya HashMap yang mengizinkan null :)
subhashis

Jawaban:

126

Saya tidak yakin apa yang Anda tanyakan, tetapi jika Anda mencari contoh ketika seseorang ingin menggunakan kunci null, saya sering menggunakannya di peta untuk mewakili kasus default (yaitu nilai yang harus digunakan jika kunci yang diberikan tidak ada):

Map<A, B> foo;
A search;
B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);

HashMapmenangani kunci null secara khusus (karena tidak dapat memanggil .hashCode()objek null), tetapi nilai null bukanlah sesuatu yang istimewa, mereka disimpan di peta seperti yang lainnya

Michael Mrozek
sumber
4
Jadi jika .hashCode () tidak dimungkinkan pada null, siapa yang memutuskan gerbong mana yang akan dimasuki kunci null?
Pacerier
26
@Pacerier Ada metode khusus di HashMap( putForNullKey) yang menanganinya; itu menyimpannya di tabel 0
Michael Mrozek
1
@MichaelMrozek baris terakhir Anda B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);Saya pikir kita cukup memanggil metode get pada kunci pencarian yang akan memiliki hasil yang sama. B val = foo.get(search);bisakah Anda mengoreksi saya jika saya mendapatkan sesuatu yang salah?
dheerajraaj
6
@ dheeraj92 Kode Anda akan disetel valke nulljika kuncinya tidak ada; milik saya mengaturnya ke nullpeta apa pun di peta. Itulah intinya, saya menyimpan nilai default non-null pada nullkunci di peta dan menggunakannya jika kunci sebenarnya tidak ada
Michael Mrozek
28

Salah satu contohnya adalah untuk memodelkan pohon. Jika Anda menggunakan HashMap untuk merepresentasikan struktur pohon, di mana kuncinya adalah induk dan nilainya adalah daftar turunan, maka nilai untuk nullkuncinya adalah simpul akar.

tony
sumber
6

Salah satu contoh penggunaan null nilai adalah saat menggunakan HashMapsebagai cache untuk hasil operasi yang mahal (seperti panggilan ke layanan web eksternal) yang mungkin kembali null.

Menempatkan nullnilai di peta kemudian memungkinkan Anda untuk membedakan antara kasus di mana operasi belum dilakukan untuk kunci tertentu ( cache.containsKey(someKey)kembali false), dan di mana operasi telah dilakukan tetapi mengembalikan nullnilai ( cache.containsKey(someKey)kembali true, cache.get(someKey)kembali null).

Tanpa nullnilai, Anda harus meletakkan beberapa nilai khusus di cache untuk menunjukkan nullrespons, atau tidak menyimpan respons itu sama sekali dan melakukan operasi setiap saat.

Zorac
sumber
3

Jawabannya selama ini hanya mempertimbangkan nilai dari sebuah nullkunci, tetapi pertanyaan juga menanyakan tentang any number of null values.

Manfaat menyimpan nilai nullterhadap kunci di HashMap sama seperti di database, dll - Anda dapat merekam perbedaan antara memiliki nilai yang kosong (misalnya string ""), dan tidak memiliki nilai sama sekali (null) .

Eborbob
sumber
2

Inilah contoh kasus saya yang hanya dibuat-buat dimana nullkuncinya dapat berguna:

public class Timer {
    private static final Logger LOG = Logger.getLogger(Timer.class);
    private static final Map<String, Long> START_TIMES = new HashMap<String, Long>();

    public static synchronized void start() {
        long now = System.currentTimeMillis();
        if (START_TIMES.containsKey(null)) {
            LOG.warn("Anonymous timer was started twice without being stopped; previous timer has run for " + (now - START_TIMES.get(null).longValue()) +"ms"); 
        }
        START_TIMES.put(null, now);
    }

    public static synchronized long stop() {
        if (! START_TIMES.containsKey(null)) {
            return 0;
        }

        return printTimer("Anonymous", START_TIMES.remove(null), System.currentTimeMillis());
    }

    public static synchronized void start(String name) {
        long now = System.currentTimeMillis();
        if (START_TIMES.containsKey(name)) {
            LOG.warn(name + " timer was started twice without being stopped; previous timer has run for " + (now - START_TIMES.get(name).longValue()) +"ms"); 
        }
        START_TIMES.put(name, now);
    }

    public static synchronized long stop(String name) {
        if (! START_TIMES.containsKey(name)) {
            return 0;
        }

        return printTimer(name, START_TIMES.remove(name), System.currentTimeMillis());
    }

    private static long printTimer(String name, long start, long end) {
        LOG.info(name + " timer ran for " + (end - start) + "ms");
        return end - start;
    }
}
aroth
sumber
Jika Anda mencoba menghentikan pengatur waktu yang tidak ada, atau yang sudah dihentikan, itu seharusnya merupakan kesalahan, jangan diabaikan.
Dana Gugatan Monica
@QPaysTaxes - Tergantung pada niat Anda. Jika Anda menginginkan utilitas ringan yang dapat dengan mudah digunakan, Anda biasanya tidak ingin throw Exceptionberkeliling. Selain itu, tidak seperti mencoba menghentikan timer yang tidak ada atau sudah berhenti adalah sesuatu yang biasanya dapat dipulihkan oleh penelepon.
Apakah
1

Contoh lain: Saya menggunakannya untuk mengelompokkan Data berdasarkan tanggal. Tetapi beberapa data tidak memiliki tanggal. Saya bisa mengelompokkannya dengan header "NoDate"

Anthone
sumber
0

Kunci null juga dapat membantu saat peta menyimpan data untuk pilihan UI di mana kunci peta mewakili bidang kacang.

Nilai bidang null yang sesuai, misalnya, akan direpresentasikan sebagai "(pilih)" dalam pemilihan UI.

Gunnar
sumber