我有以下列表并使用
LinkedHashMap
。
我想将key的值增加
1
(如果地图中不存在,则从0
开始,我添加+1
):
int nums[] = new int[]{4, 10, 5, 4, 2, 10};
Map<Integer, Integer> map = new LinkedHashMap<>();
for (int i = 0; i < nums.length; i++) {
int key = nums[i];
int value = map.getOrDefault(key, 0) + 1;
// I want to use merge method, but have no idea
// what should be the 3 rd parameter denoted by "<??????>"
int value = map.merge(key, 1, <??????>)
map.put(key, value);
}
但是,我想使用
merge()
方法,但不知道“<??????>
”表示的第三个参数应该是什么(参见代码)。
那么,在这种情况下如何使用 merge 方法呢?
merge方法的第三个参数是
BiFunction
,即接受两个泛型类型V(值的类型)参数并返回所述值的合并的功能接口。
假设在您的代码中您试图获取每个键的频率,尽管您写的是“它从 0 开始,我添加 +1”,但这是您尝试的示例。
在您的情况下,由于对于每个键,您总是映射值 1 然后递增它,因此您可以通过将两个冲突值
BiFunction
相加,或者通过将 1 添加到先前映射的值来实现 (v1, v2) -> v1 + v2
合并价值(v1, v2) -> v1 + 1
。
int nums[] = new int[]{4, 10, 5, 4, 2, 10};
Map<Integer, Integer> map = new LinkedHashMap<>();
for (int i = 0; i < nums.length; i++) {
map.merge(nums[i], 1, (v1, v2) -> v1 + 1);
//Alternatively summing the two values
//map.merge(nums[i], 1, (v1, v2) -> v1 + v2);
}
System.out.println(map);
但是,如果您的目标是获取按键冲突的数量而不是频率,那么只需将初始值 1 替换为 0,上面的代码仍然可以工作。
int nums[] = new int[]{4, 10, 5, 4, 2, 10};
Map<Integer, Integer> map = new LinkedHashMap<>();
for (int i = 0; i < nums.length; i++) {
map.merge(nums[i], 0, (v1, v2) -> v1 + 1);
}
System.out.println(map);
如果仅需要对整数值进行递增/递减,则更经济的方法(创建更少的
Integer
实例)是使用可变整数类(如 AtomicInteger
)作为值类型。
递增/递减将变得微不足道:
Map<String, AtomicInteger> map = new HashMap<>();
// Create a mapping for key "foo" if not exists, then increment
int n = map.computeIfAbsent("foo", (k) -> new AtomicInteger())
.incrementAndGet(); // or addAndGet() or similar
如果地图中不存在,则它从
开始,我添加0
+1
为了从
zero
开始计数,您可以使用方法compute()
,该方法需要一个key和remappingFunction,允许根据key和现有值计算新值 :
int nums[] = new int[]{4, 10, 5, 4, 2, 10};
Map<Integer, Integer> map = new LinkedHashMap<>();
for (int num : nums) {
map.compute(num, (k, v) -> v == null ? 0 : v + 1);
}
System.out.println(map);
输出:
{4=1, 10=1, 5=0, 2=0}
4
和 10
- 出现两次,因此将与 1
的值相关联;5
和 2
- 只会遇到一次,因此会映射到 0
的值(因为第一次遇到的键是必需的,即地图中不存在) )但是,我想用
merge()
使用
map.merge(num, 1, Integer::sum);
,地图中不存在的键将从一开始就与1
的值相关联。 IE。作为第三个参数提供的 remappingFunction 将不会被执行,并且由提供的 key 和 value 组成的新条目将被放置到映射中。
然后,当第二次、第三次等遇到这样的键时,remappingFunction将用于组合旧值和新值(
1
),即值将增加一。
为了获得与上面所示的
merge()
相同的结果,我们可以在 merge()
周围放置条件。在条件内部,我们可以使用 putIfAbsent()
来初始化条目 will 0
。如果给定的键不存在,putIfAbsent()
将返回null
,否则现有值:
int nums[] = new int[]{4, 10, 5, 4, 2, 10};
Map<Integer, Integer> map = new LinkedHashMap<>();
for (int num : nums) {
if (map.putIfAbsent(num, 0) != null) {
map.merge(num, 1, Integer::sum);
}
}
输出:
{4=1, 10=1, 5=0, 2=0}