Mungkin sedikit terlambat tapi ini dua sen saya.
Jika Anda menggunakan Java 8 maka Anda dapat menggunakan metode computeIfPresent . Jika nilai untuk kunci yang ditentukan ada dan bukan nol maka akan mencoba menghitung pemetaan baru yang diberikan kunci dan nilai yang dipetakan saat ini.
final Map<String,Integer> map1 = new HashMap<>();
map1.put("A",0);
map1.put("B",0);
map1.computeIfPresent("B",(k,v)->v+1); //[A=0, B=1]
Kita juga dapat menggunakan metode lain putIfAbsent untuk meletakkan kunci. Jika kunci yang ditentukan belum dikaitkan dengan nilai (atau dipetakan ke nol) maka metode ini mengaitkannya dengan nilai yang diberikan dan mengembalikan nol, jika tidak mengembalikan nilai saat ini.
Jika peta dibagikan di seluruh utas maka kita dapat menggunakan ConcurrentHashMap
dan AtomicInteger . Dari dokumen:
Sebuah AtomicInteger
adalah nilai int yang dapat diperbarui atom. AtomicInteger digunakan dalam aplikasi seperti penghitung yang bertambah secara atom, dan tidak dapat digunakan sebagai pengganti Integer. Namun, kelas ini memperluas Nomor untuk memungkinkan akses seragam oleh alat dan utilitas yang berhubungan dengan kelas berbasis numerik.
Kita dapat menggunakannya seperti yang ditunjukkan:
final Map<String,AtomicInteger> map2 = new ConcurrentHashMap<>();
map2.putIfAbsent("A",new AtomicInteger(0));
map2.putIfAbsent("B",new AtomicInteger(0)); //[A=0, B=0]
map2.get("B").incrementAndGet(); //[A=0, B=1]
Satu hal yang perlu diperhatikan adalah kita memohon get
untuk mendapatkan nilai untuk kunci B
dan kemudian meminta incrementAndGet()
nilainya yang tentu saja AtomicInteger
. Kami dapat mengoptimalkannya karena metode putIfAbsent
mengembalikan nilai kunci jika sudah ada:
map2.putIfAbsent("B",new AtomicInteger(0)).incrementAndGet();//[A=0, B=2]
Di samping catatan jika kita berencana untuk menggunakan AtomicLong maka sesuai dokumentasi di bawah pertentangan yang tinggi diharapkan throughput LongAdder secara signifikan lebih tinggi, dengan mengorbankan konsumsi ruang yang lebih tinggi. Periksa juga pertanyaan ini .