Nó có thể hơi muộn nhưng đây là hai xu của tôi.
Nếu bạn đang sử dụng Java 8 thì bạn có thể sử dụng phương thức compute IfPftime . Nếu giá trị của khóa được chỉ định hiện diện và không có giá trị thì nó sẽ cố gắng tính toán một ánh xạ mới được cung cấp cho khóa và giá trị được ánh xạ hiện tại của nó.
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]
Chúng ta cũng có thể sử dụng một phương thức khác đặt IfAbsent để đặt khóa. Nếu khóa được chỉ định chưa được liên kết với một giá trị (hoặc được ánh xạ thành null) thì phương thức này liên kết nó với giá trị đã cho và trả về null, nếu không thì trả về giá trị hiện tại.
Trong trường hợp bản đồ được chia sẻ trên các luồng thì chúng ta có thể sử dụng ConcurrentHashMap
và AtomicInteger . Từ tài liệu:
An AtomicInteger
là một giá trị int có thể được cập nhật nguyên tử. Một AtomicInteger được sử dụng trong các ứng dụng như bộ đếm tăng nguyên tử và không thể được sử dụng để thay thế cho Integer. Tuy nhiên, lớp này mở rộng Số để cho phép truy cập thống nhất bằng các công cụ và tiện ích liên quan đến các lớp dựa trên số.
Chúng ta có thể sử dụng chúng như được hiển thị:
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]
Một điểm cần quan sát là chúng ta đang gọi get
để lấy giá trị cho khóa B
và sau đó gọi incrementAndGet()
giá trị của nó là điều tất nhiên AtomicInteger
. Chúng ta có thể tối ưu hóa nó khi phương thức putIfAbsent
trả về giá trị cho khóa nếu đã có:
map2.putIfAbsent("B",new AtomicInteger(0)).incrementAndGet();//[A=0, B=2]
Một lưu ý nữa là nếu chúng tôi dự định sử dụng AtomicLong thì theo tài liệu dưới sự tranh chấp cao, thông lượng dự kiến của LongAdder sẽ cao hơn đáng kể, với chi phí tiêu thụ không gian cao hơn. Cũng kiểm tra câu hỏi này .