2013-04-14 3 views
0

Когда я был кодированием, мне пришло в голову вопрос, который есть, если часть значения (целое число) в HashMap может автоматически увеличивать в следующем сценарии?Значение автоинкремента HashMap

Map<String, Integer> dictionary = new HashMap<String, Integer>();  
dictionary.put("a",1); 
dictionary.put("b",1); 
+0

с использованием 'для loop' это не вариант? –

+0

@Mahan Я просто хочу знать, будет ли значение 1 добавлено к 2 автоматически ... это просто простой пример – Justin

+0

Это не хороший дизайн api. Вы всегда можете увеличить и поместить в карту. – Jayan

ответ

3

Вы можете использовать изменяемые Integer, и я предпочитаю вы можете использовать AtomicInteger

Map<Key, AtomicInteger> dictionary = new HashMap<String, AtomicInteger>(); 
dictionary.get(key).incrementAndGet(); 

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html

, но я действительно предпочитаю вам, что вы должны сделать это традиционным способом, который делает for loop, потому что что делает вещи действительно сложными, не делает никакого решения вообще

+0

+1: для меня это самое чистое решение. – acdcjunior

+1

Если ключ добавлен в первый раз, dictionary.get (key) возвращает значение null. – Timmy

+0

@Timmy, да, конечно, AtomicInteger должен быть создан с новым AtomicInteger() –

2

Вы можете написать собственный класс AutoIncrementHashMap который внутренне использует HashMap, имеет автоматический увеличивающиеся переменную count и put(String) метода, который добавляет String элемент и увеличивает counter каждый раз.

3

Вы можете использовать Multiset из рамок Guava, который открыт Google.

Использование Multiset может значительно упростить вашу жизнь.

Multiset<String> set = HashMultiset.create(); 
    set.add("abc"): 
    set.add("acd"); 
    set.add("abc"); 

    // use set.count(Object) to get the counter of the object 
    int c = set.count("abc"); 

    // or iterate through the set to get each object and its count 
    for (Multiset.Entry<String> entry : set.entrySet()){ 
     String str = entry.getElement(); 
     int count = entry.getCount(); 
    } 

По сравнению с традиционным способом, который использует обычные HashMaps:

Map<String, Integer> map = new HashMap<String, Integer>(); 

    public void add(String str){ 
     Integer oldValue = map.get(str); 
     if (oldValue == null){ 
      map.put(str, 1); 
     } else{ 
      map.put(str, oldValue + 1); 
     } 
    } 

Даже если вы используете изменяемые счетчики как значения HashMap, код по-прежнему очень громоздкий.

Map<String, AtomicInteger> map = new HashMap<String, AtomicInteger>(); 

    public void add(String str){ 
     AtomicInteger counter = map.get(str); 
     if (counter == null){ 
      counter = new AtomicInteger(); 
      map.put(str, counter); 
     } 
     counter.incrementAndGet(); 
    } 
+0

+1 для guava, это, безусловно, лучший способ пойти сюда. – Zarathustra

1

Самым простым и быстрым решением является использование TObjectIntHashMap

TObjectIntHashMap<String> map = new TObjectIntHashMap<String>(); 

public void add(String str){ 
    map.adjustOrPutValue(str, 1, 1); 
} 

примитивы поддержки Trove в коллекции делает их более эффективными, и в этом случае есть метод, который делает то, что вам нужно.

0

Вы можете создать класс поддержки:

public class HashMapInteger<K> extends HashMap<K,Integer> { 
      public void increment(K key) { 
      if(super.containsKey(key)) 
       super.put(key,super.get(key)+1); 
      else 
       super.put(key,new Integer(1)); 
      } 

      public void increment(K key, int val) { 
       if(super.containsKey(key)) 
        super.put(key,super.get(key)+val); 
       else 
        super.put(key,new Integer(val)); 
       } 
     } 

использовать:

HashMapInteger<String> map = new HashMapInteger<String>(); 
map.increment("abc"); 
map.increment("abc"); 
System.out.println(map.get("abc"));//Output is 2 
Смежные вопросы