如何在 Java 中使用合并方法增加 HashMap 值?
How to increase HashMap value using merge method in Java?
我有以下 list 并使用 LinkedHashMap
.
我想将 key 的 value 增加 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()
方法,但不知道“<??????>
”表示的第三个参数应该是什么(见代码).
那么,在这种情况下如何使用合并方法?
if the key is not present in the map, it starts from 0
and I add +1
为了从 zero
开始计数,您可以使用方法 compute()
,它需要一个 key 和 remappingFunction 允许根据 key 和 existing value:[=37 计算 new value =]
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
的值(因为第一次遇到的键需要它时间,即不存在在地图中)
However, I want to use merge()
对于 map.merge(num, 1, Integer::sum);
,映射中不存在的键将从一开始就与 1
的值相关联。 IE。作为第三个参数提供的 remappingFunction 将不会被执行,并且由提供的 key 和 value[=65 组成的新条目=] 将被放入地图中。
然后当第二次、第三次等遇到此类键时,remappingFunction 将用于组合旧值和新值 (1
),即值将增加一。
要使用 merge()
获得与上面所示相同的结果,我们可以在 merge()
周围放置条件。在条件中,我们可以使用 putIfAbsent()
来初始化入口 will 0
。如果给定的键不存在,putIfAbsent()
将 return 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}
merge 方法的第三个参数是 BiFunction
,即接受两个泛型 V 参数(您的值的类型)并返回所述值的合并的功能接口。
假设您在您的代码中尝试获取每个键的频率,尽管您写的是“它从 0 开始,我添加 +1”,这里是您尝试的示例。
合并操作由您决定,在您的情况下,它仅包括保留第一个值(已经存在于您的地图中的值),将其递增 1 并忽略第二个值。合并也可以简单地包括将第一个值和第二个值相加,因为对于每个键,您只是映射值 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);
如果整数值只需要 increment/decrement,更经济的方法(创建的 Integer
的实例较少)将使用可变整数 class(如 AtomicInteger
) 作为值类型。
Increment/Decrement 将是微不足道的:
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
我有以下 list 并使用 LinkedHashMap
.
我想将 key 的 value 增加 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()
方法,但不知道“<??????>
”表示的第三个参数应该是什么(见代码).
那么,在这种情况下如何使用合并方法?
if the key is not present in the map, it starts from
0
and I add+1
为了从 zero
开始计数,您可以使用方法 compute()
,它需要一个 key 和 remappingFunction 允许根据 key 和 existing value:[=37 计算 new value =]
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
的值(因为第一次遇到的键需要它时间,即不存在在地图中)
However, I want to use
merge()
对于 map.merge(num, 1, Integer::sum);
,映射中不存在的键将从一开始就与 1
的值相关联。 IE。作为第三个参数提供的 remappingFunction 将不会被执行,并且由提供的 key 和 value[=65 组成的新条目=] 将被放入地图中。
然后当第二次、第三次等遇到此类键时,remappingFunction 将用于组合旧值和新值 (1
),即值将增加一。
要使用 merge()
获得与上面所示相同的结果,我们可以在 merge()
周围放置条件。在条件中,我们可以使用 putIfAbsent()
来初始化入口 will 0
。如果给定的键不存在,putIfAbsent()
将 return 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}
merge 方法的第三个参数是 BiFunction
,即接受两个泛型 V 参数(您的值的类型)并返回所述值的合并的功能接口。
假设您在您的代码中尝试获取每个键的频率,尽管您写的是“它从 0 开始,我添加 +1”,这里是您尝试的示例。
合并操作由您决定,在您的情况下,它仅包括保留第一个值(已经存在于您的地图中的值),将其递增 1 并忽略第二个值。合并也可以简单地包括将第一个值和第二个值相加,因为对于每个键,您只是映射值 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);
如果整数值只需要 increment/decrement,更经济的方法(创建的 Integer
的实例较少)将使用可变整数 class(如 AtomicInteger
) 作为值类型。
Increment/Decrement 将是微不足道的:
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