简体   繁体   English

java HashMap 未更新特定键的 integer 值

[英]java HashMap not updating integer value for a specific key

package cdlKata;

import java.util.HashMap;
import java.util.Map;

class Item2 {
  private String s;
  public Item2(String s) { this.s = s; }
  public String getS() { return s; }
}

class Basket2 {
  private Map<Item2, Integer> items;

  public Basket2() { items = new HashMap<>(); }

  public Map<Item2, Integer> getItems() { return items; }

  public void addItemToBasket(Item2 item) {
    items.put(item, items.getOrDefault(item,0) + 1);
  }

  public void printBasket() {
    items.entrySet().forEach(e->{ System.out.println(e.getKey().getS() + " " + e.getValue());});
  }
}

public class Main2 {

  public static void main(String[] args) {
    Basket2 basket;
    basket = new Basket2();
    basket.addItemToBasket(new Item2("A"));
    basket.addItemToBasket(new Item2("A"));
    basket.printBasket();
  }
}

Result is:结果是:

A 1一个 1
A 1一个 1

with basket size = 2. What I want is:篮子大小= 2。我想要的是:

A 2 A2

with basket size 1.篮子尺寸 1。

if I turn Item2 into a String I got no issue.如果我将 Item2 变成 String 我没有问题。 Don't understans why it is not working.不明白为什么它不起作用。


You created two different instances as below您创建了两个不同的实例,如下所示

basket.addItemToBasket(new Item2("A"));
basket.addItemToBasket(new Item2("A"));

You are expecting it to be equal.你期望它是平等的。 It will not be the case.情况不会如此。

You have to override hashcode and equals您必须覆盖hashcodeequals

According to the logic of work of HashMap, you must override your keys' hashcode() and equals() methods.根据 HashMap 的工作逻辑,你必须重写你的键的 hashcode() 和 equals() 方法。 PS Also I would suggest you to use in this case merge method of map instead of put. PS 另外,我建议您在这种情况下使用 map 的合并方法而不是 put。

map.merge(key, 1, Integer::sum)

Since you are using Map of object,Integer the output:由于您使用的是 Map 的 object,Integer Z78E6221F6393D1356681DB398F14CED6

A 1一个 1

A 1一个 1

is correct, but you are expecting output: A 2是正确的,但你期待 output: A 2

for which you need to create Map of String,Integer ie.为此,您需要创建 Map 的字符串,Integer 即。 map of item2.getS() and Integer. item2.getS() 和 Integer 的 map。

The reason it is not working is because you Mapped object and Integer, and you are adding item to basket by creating new objects each time.它不起作用的原因是因为您映射了 object 和 Integer,并且您每次都通过创建新对象将项目添加到购物篮。

So, the solution will be like this.因此,解决方案将是这样的。

    package cdlKata;

    import java.util.HashMap;
    import java.util.Map;

    class Item2 {
        private String s;
        public Item2(String s) { this.s = s; }
        public String getS() { return s; }
    }

    class Basket2 {
        private Map<String, Integer> items;

        public Basket2() { items = new HashMap<>(); }

        public Map<String, Integer> getItems() { return items; }

        public void addItemToBasket(Item2 item) {
            items.put(item.getS(), items.getOrDefault(item.getS(),0) + 1);
        }

        public void printBasket() {
            items.entrySet().forEach(e->{ System.out.println(e.getKey() + " " + e.getValue());});
        }
    }

    public class Stack {

        public static void main(String[] args) {
            Basket2 basket;
            basket = new Basket2();
            basket.addItemToBasket(new Item2("A"));
            basket.addItemToBasket(new Item2("A"));
            basket.printBasket();
        }
    }

Well... You are missing equals/hashCode in your class.好吧...您在 class 中缺少 equals/hashCode。

See this answer for more info: Why do I need to override the equals and hashCode methods in Java?有关更多信息,请参阅此答案: 为什么我需要覆盖 Java 中的 equals 和 hashCode 方法?

For exactly your class just define these methods:对于您的 class 只需定义这些方法:

class Item2 {
    private String s;
    public Item2(String s) { this.s = s; }
    public String getS() { return s; }


    @Override public boolean equals(Object o)
    {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        Item2 item2 = (Item2) o;

        return s != null ? s.equals(item2.s) : item2.s == null;
    }


    @Override public int hashCode()
    {
        return s != null ? s.hashCode() : 0;
    }
}

Is is a common mistake of using hash.是使用 hash 的常见错误。 You should implement hashCode and equals for Item class.您应该为项目 class 实现 hashCode 和 equals。

class Item2 {
  private String s;
  public Item2(String s) { this.s = s; }
  public String getS() { return s; }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Item2)) return false;
    Item2 item2 = (Item2) o;
    return Objects.equals(getS(), item2.getS());
  }

  @Override
  public int hashCode() {
    return Objects.hash(getS());
  }
}

Without that, HashMap will consider two objects (even the same value) are different, Therefore, it will put as a new Object.没有那个,HashMap 会认为两个对象(即使是相同的值)是不同的,因此,它将作为一个新的 Object。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM