关于hashmaps和for循环的基本内容对我来说很难掌握。我想要做的是每次数组列表中的值与键字符串相关联时,基于Keys方法将与键相关联的值添加+1。
因此,如果数组列表中有3个值为正值,则hashmap应该具有将“positive”键更新为3的值。
任何帮助/建议将不胜感激 - 谢谢。
drush entup
答案 0 :(得分:2)
Map.put(k, v)
始终会覆盖您之前的值。您可以使用"传统方法":
if (!map.containsKey("positive"))
map.put("positive", 0);
map.put("positive", map.get("positive") + 1);
或者更好地使用为这种情况添加的新merge
功能:
map.merge("positive", 1, (prev, one) -> prev + one);
但是使用Math.signum()
和流收集器可以大大缩短整个逻辑:
Map<Double, Long> collect = inputs.stream()
.collect(Collectors.groupingBy(Math::signum,
Collectors.counting()));
System.out.println("positive: " + collect.get(1.0));
System.out.println("negative: " + collect.get(-1.0));
System.out.println("zero: " + collect.get(0.0));
答案 1 :(得分:2)
让我们快速整理,让我们创建一个enum
并删除那些你没有在任何地方定义的讨厌的String
常量:
public enum Sign {
POSITIVE,
ZERO,
NEGATIVE;
public static Sign of(double d) {
if (d > 0) {
return POSITIVE;
}
if (d < 0) {
return NEGATIVE;
}
return ZERO;
}
}
现在我们可以简单地编写一个方法来增加适当的值:
public void increment(final double d, final Map<Sign, Integer> count) {
count.merge(Sign.of(d), 1, Integer::sum);
}
快速测试:
final Map<Sign, Integer> count = new EnumMap<>(Sign.class);
increment(0, count);
System.out.println(count);
increment(-1, count);
System.out.println(count);
increment(1, count);
System.out.println(count);
increment(-2, count);
System.out.println(count);
increment(2, count);
System.out.println(count);
输出:
{ZERO=1}
{NEGATIVE=1, ZERO=1}
{POSITIVE=1, NEGATIVE=1, ZERO=1}
{POSITIVE=1, NEGATIVE=2, ZERO=1}
{POSITIVE=2, NEGATIVE=2, ZERO=1}
那么这个神奇的工作原理是什么?来自the documentation for Map.merge
如果指定的键尚未与值关联或是 与null关联,将其与给定的非null值相关联。 否则,将相关值替换为给定的结果 重新映射函数,如果结果为null则删除。这种方法可以 在组合键的多个映射值时使用。
所以key
作为merge
的第一个参数 - 在Sign.of(d)
的情况下;这会选择正确的存储桶。如果映射到key
的值为null
,那么它只是将key
的映射放到作为第二个参数传递的value
- 在这种情况下{{1} }。否则它会变得更复杂;它采用当前映射到该键的值,并使用作为第三个参数传递的1
。这是一个remappingFunction
,所以它需要两个BiFunction<V,V,V>
类型的参数,V
类型并返回一个参数 - 它将两者合并在一起。在这里,我们使用value
来获取现有Integer::sum
,新value
并返回其value
。
但我们可以更进一步,我们可以使用sum
对任意Stream
执行此操作:
double[]
注意:我在这里使用了EnumMap
,public Map<Sign, Long> count(final double[] d) {
return Arrays.stream(d)
.mapToObj(Sign::of)
.collect(groupingBy(identity(), () -> new EnumMap<>(Sign.class), counting()));
}
针对使用Map
作为关键进行了优化。
答案 2 :(得分:1)
你可以用流简洁地解决它。您需要一个将值转换为negative
/ zero
/ positive
键的函数。然后只需通过此键与计数收集器进行分组。它基本上是一个双线:
List<Double> values = Arrays.asList(-4.56,-4.66,0.0, 6.0, -6.99, 6.97);
Function<Double, String> toKey = v -> v < 0 ? "negative" : (v == 0 ? "zero" : "positive");
Map<String, Long> result = values
.stream()
.collect(Collectors
.groupingBy(
toKey,
Collectors.counting()));
答案 3 :(得分:0)
HashMap的方法<div class="form-group">
{{ form_label(form.amenities, '', {'label_attr': {'class': 'col-md-4 control-label amenities', 'data-location-id': location.id}}) }}
<div class="col-md-8">
{{ form_widget(form.amenities, {'attr': {'class': 'form-control'}}) }}
{{ form_errors(form.amenities) }}
</div>
</div>
使用值映射唯一键。如果提供的密钥已经存在于地图中,它将使用新值替换现有值。
您需要定义类似于下面的方法。
put
对于比较值的书写方法,您可以参考https://stackoverflow.com/a/10400718/504133