【问题标题】:Duplicate Value insertion in HashmapHashmap 中的重复值插入
【发布时间】:2016-08-05 03:49:41
【问题描述】:

有一个Hashmap(o),它以字符串为键,以Order Object为值。 Order 有一个 OrderLines 的 Arraylist。在这里,我必须向地图添加多个订单。问题是我的哈希图打印出唯一的第一个和第二个键(顺序 1 和顺序 2),但最后插入的值作为两个键的值(所有条目中的重复顺序)。你能帮我调试一下吗?

主类

    Map<String, Order> o = new HashMap<String, Order>();

    Order c = new Order();

    c.add(new OrderLine(new Item("book", (float) 12.49), 1));
    c.add(new OrderLine(new Item("music CD", (float) 14.99), 1));

    o.put("Order 1", c);

    // Reuse cart for an other order
    c.clearCart(); // this.orderLines.clear() in the order class 

    c.add(new OrderLine(new Item("imported box of chocolate", 10), 1));
    c.add(new OrderLine(new Item("imported bottle of perfume", (float)     47.50), 1));

    o.put("Order 2", c);

    for (Map.Entry<String, Order> entry : o.entrySet()) {
        System.out.println("*******" + entry.getKey() + entry.getValue().get(0).getItem().getDescription() + "*******");
    }

订单类

class Order {

private List<OrderLine> orderLines = new ArrayList<>();

public void add(OrderLine o) throws Exception {
    orderLines.add(o);
}

public OrderLine get(int i) {
    return orderLines.get(i);
}

public void clearCart() {
    this.orderLines.clear();
}
}

OrderLine 类:

private int quantity;
private Item item;

public OrderLine(Item item, int quantity) throws Exception {
    if (item == null) {
        System.err.println("ERROR - Item is NULL");
        throw new Exception("Item is NULL");
    }
    assert quantity > 0;
    this.item = item;
    this.quantity = quantity;
}

public Item getItem() {
    return item;
}

public int getQuantity() {
    return quantity;
}
}

物品类别:

class Item {

    private String description;
    private float price;

    public Item(String description, float price) {
        super();
        this.description = description;
        this.price = price;
    }

    public String getDescription() {
        return description;
    }

    public float getPrice() {
        return price;
    }
    }

【问题讨论】:

  • OrderLine 类在哪里。这就是你的代码的作用。发布整个代码,我会建议修复。看起来 c.clearCart() 无法清除购物车
  • 添加所有代码
  • 如何在主类的for循环中的SOP中得到entry.getValue().get(0)
  • 看我的回答。这个问题不应该像现在这样被否决。有足够多的代码来理解这个问题,而答案实际上就在 Java 的幕后工作中。 OP因为不知道问题而找不到答案,这是完全可以理解的。
  • 不知道为什么人们拒绝投票

标签: java list arraylist collections hashmap


【解决方案1】:

虽然 Java 是按值传递的,但更改引用末尾的内容是完全有效的。这就是你正在做的事情,尽管是无意的。

想想你在做什么:你将c添加到列表中,然后清除c,重新初始化它,然后再次添加。

由于您从未使用过new 关键字,因此您实际上从未为c. 分配新的内存部分它仍然指向相同的Order. 同时,您没有添加c 的克隆到列表中。你添加了c.

换句话说,当您调用c.clearCart(), 时,您还清除了列表o 中的第一个Order,正如Order 所说 c.

您可以通过替换使用new 关键字:

c.clearCart();

c = new Order();

或者,您可以将c 的克隆添加到列表o 而不是c 本身,这样当您调用c.clearCart(), 时,您不会清除列表o. 中的第一个元素,换句话说,替换:

o.put("Order 1", c);

o.put("Order 1", c.clone());

更多信息请参见this question

编辑:

我忘记了一部分,尽管它可能很明显。我说过清除c 也将清除列表o, 中的第一个元素,因为该元素 c. 但是,我忘了提到,通过转换,重新初始化c 也意味着同时重新初始化这个元素。因此,当您再次添加 c 时,您将使用相同的字段初始化两个元素。

【讨论】:

    猜你喜欢
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-23
    • 2021-03-15
    • 2019-05-21
    • 1970-01-01
    相关资源
    最近更新 更多