Answers:
map.put(key, map.get(key) + 1);
应该没事。它将更新现有映射的值。请注意,这使用自动装箱。在map.get(key)
我们的帮助下,您可以获得相应密钥的值,然后您可以根据需要进行更新。在这里,我将值增加1。
getOrDefault
,例如:map.put(key, count.getOrDefault(key, 0) + 1);
您可以使用computeIfPresent
method并为其提供一个映射函数,该函数将被调用以基于现有值来计算新值。
例如,
Map<String, Integer> words = new HashMap<>();
words.put("hello", 3);
words.put("world", 4);
words.computeIfPresent("hello", (k, v) -> v + 1);
System.out.println(words.get("hello"));
或者,您可以使用merge
method,其中1为默认值,函数将现有值增加1:
words.merge("hello", 1, Integer::sum);
此外,有一堆其他有用的方法,例如putIfAbsent
,getOrDefault
,forEach
等。
null
(例如words.put("hello", null);
)时,第一个lambda表达式one不能始终如一地工作,结果仍然null
不是1
我期望的那样。
compute()
它,它也会处理null
值。
.merge
是我的解决方案Integer::sum
。
hashmap.put(key, hashmap.get(key) + 1);
该方法put
将替换现有键的值,如果不存在则将创建它。
nullPointer Exception
。
null + 1
因为这将尝试将inbox拆null
成整数以进行增量。
简化的Java 8方式:
map.put(key, map.getOrDefault(key, 0) + 1);
这使用HashMap的方法来检索键的值,但是如果无法检索到键,它将返回指定的默认值(在这种情况下为'0')。
核心Java支持此功能:HashMap <K,V> getOrDefault(Object key,V defaultValue)
替换Integer
为AtomicInteger
并在其上调用incrementAndGet
/ getAndIncrement
方法之一。
一种替代方法是将一个包装int
到您自己的MutableInteger
具有increment()
方法的类中,您只需要解决线程安全问题。
MutableInteger
更好,因为AtomicInteger
使用volatile
会产生开销。我会用int[1]
代替MutableInteger
。
一线解决方案:
map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);
@Matthew的解决方案是最简单的,并且在大多数情况下会表现良好。
如果您需要高性能,则AtomicInteger是@BalusC更好的解决方案。
但是,一种更快的解决方案(提供的线程安全性不是问题)是使用TObjectIntHashMap,它提供了增量(密钥)方法,并且比创建AtomicIntegers使用的原语和对象更少。例如
TObjectIntHashMap<String> map = new TObjectIntHashMap<String>()
map.increment("aaa");
可能还不晚,但这是我的两分钱。
如果您使用的是Java 8,则可以使用computeIfPresent方法。如果指定键的值存在且非空,则它会尝试计算给定键及其当前映射值的新映射。
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]
我们还可以利用putIfAbsent的另一种方法来放置密钥。如果指定的键尚未与值关联(或映射为null),则此方法将其与给定值关联并返回null,否则返回当前值。
如果映射在线程之间共享,那么我们可以使用ConcurrentHashMap
和AtomicInteger。从文档中:
An
AtomicInteger
是可以自动更新的int值。AtomicInteger用于原子递增计数器之类的应用程序,并且不能用作Integer的替代品。但是,此类确实扩展了Number,以允许处理基于数字的类的工具和实用程序进行统一访问。
我们可以如下所示使用它们:
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]
要观察的一点是,我们正在调用get
以获取键的值B
,然后调用incrementAndGet()
其值,这当然是正确的AtomicInteger
。我们可以对其进行优化,因为该方法putIfAbsent
将返回键的值(如果已存在):
map2.putIfAbsent("B",new AtomicInteger(0)).incrementAndGet();//[A=0, B=2]
附带一提,如果我们计划使用AtomicLong,则根据高争用条件下的文档,LongAdder的预期吞吐量会显着提高,但要消耗更多的空间。还要检查这个问题。
没有NullPointerException的更干净的解决方案是:
map.replace(key, map.get(key) + 1);
由于信誉欠佳,我无法评论一些答案,因此我将发布一个已应用的解决方案。
for(String key : someArray)
{
if(hashMap.containsKey(key)//will check if a particular key exist or not
{
hashMap.put(hashMap.get(key),value+1);// increment the value by 1 to an already existing key
}
else
{
hashMap.put(key,value);// make a new entry into the hashmap
}
}
使用for
循环来增加索引:
for (int i =0; i<5; i++){
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("beer", 100);
int beer = map.get("beer")+i;
System.out.println("beer " + beer);
System.out ....
}
这里存在对该问题的误导性答案,这意味着如果键存在,则Hashtable的put方法将替换现有值,这对于Hashtable而言并非如此,而对于HashMap而言则并非如此。请参阅Javadoc for HashMap http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V%29
Integer i = map.get(key);
if(i == null)
i = (aValue)
map.put(key, i + 1);
要么
Integer i = map.get(key);
map.put(key, i == null ? newValue : i + 1);
整数是原始数据类型http://cs.fit.edu/~ryan/java/language/java-data.html,因此您需要将其取出,进行一些处理,然后再放回去。如果您拥有的值不是原始数据类型,则只需将其取出,处理它,而无需将其放回哈希图中。
使用内置的功能'computeIfPresent'的Java8
例:
public class ExampleToUpdateMapValue {
public static void main(String[] args) {
Map<String,String> bookAuthors = new TreeMap<>();
bookAuthors.put("Genesis","Moses");
bookAuthors.put("Joshua","Joshua");
bookAuthors.put("Judges","Samuel");
System.out.println("---------------------Before----------------------");
bookAuthors.entrySet().stream().forEach(System.out::println);
// To update the existing value using Java 8
bookAuthors.computeIfPresent("Judges", (k,v) -> v = "Samuel/Nathan/Gad");
System.out.println("---------------------After----------------------");
bookAuthors.entrySet().stream().forEach(System.out::println);
}
}