001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.reef.io.network.group.impl.utils; 020 021import java.util.HashMap; 022import java.util.Map; 023import java.util.logging.Level; 024import java.util.logging.Logger; 025 026/** 027 * Utility class to provide a map that allows to 028 * add multiple keys and automatically 029 * incrementing the count on each add 030 * decrementing the count on each remove 031 * and removing key on count==0. 032 */ 033public class CountingMap<L> { 034 private static final Logger LOG = Logger.getLogger(CountingMap.class.getName()); 035 private final Map<L, Integer> map = new HashMap<>(); 036 037 public boolean containsKey(final L value) { 038 return map.containsKey(value); 039 } 040 041 public int get(final L value) { 042 if (!containsKey(value)) { 043 return 0; 044 } 045 return map.get(value); 046 } 047 048 public boolean isEmpty() { 049 return map.isEmpty(); 050 } 051 052 public void clear() { 053 map.clear(); 054 } 055 056 public void add(final L value) { 057 int cnt = map.containsKey(value) ? map.get(value) : 0; 058 map.put(value, ++cnt); 059 } 060 061 public boolean remove(final L value) { 062 if (!map.containsKey(value)) { 063 return false; 064 } 065 int cnt = map.get(value); 066 --cnt; 067 if (cnt == 0) { 068 map.remove(value); 069 } else { 070 map.put(value, cnt); 071 } 072 return true; 073 } 074 075 @Override 076 public String toString() { 077 return map.toString(); 078 } 079 080 public static void main(final String[] args) { 081 final CountingMap<String> strMap = new CountingMap<>(); 082 strMap.add("Hello"); 083 LOG.log(Level.INFO, "OUT: {0}", strMap); 084 strMap.add("World"); 085 LOG.log(Level.INFO, "OUT: {0}", strMap); 086 strMap.add("Hello"); 087 LOG.log(Level.INFO, "OUT: {0}", strMap); 088 strMap.add("Hello"); 089 LOG.log(Level.INFO, "OUT: {0}", strMap); 090 strMap.add("World!"); 091 LOG.log(Level.INFO, "OUT: {0}", strMap); 092 strMap.remove("Hello"); 093 LOG.log(Level.INFO, "OUT: {0}", strMap); 094 strMap.remove("World"); 095 LOG.log(Level.INFO, "OUT: {0}", strMap); 096 } 097}