从HashMap中删除值

时间:2015-03-10 19:00:40

标签: java

在学习java中的集合的早期阶段....

是否可以从HashMap中删除值,但保留其对应的键?如果是这样,那会被认为是不好的做法吗?

我已经写了以下测试来检查:

HashMap<String, String> map = new HashMap<String, String>();

map.put("one", "1");
map.put("two", "2");
map.put("three", "3");

map.values().remove("3");

//try map.get("one").remove("1");

for (String name: map.keySet()){

    String key = name;
        String value = map.get(name);

              System.out.println(key + " " + value);  

}

希望它会回归:

一个1 两个2 3

但它会返回:

一个1 两个2

我无法在javadocs或在这里找到任何可以帮助我回答我的难题的事情(至少我明白了!)。

仅供参考 - 想要这样做的原因:

我有一个HashMap来存储Person(Key)和Ticket(Value)。

当一个人买票时,他们会被添加到HashMap中,以便我可以参考哪些人已经有票。 (他们只允许一张票/人)。

当故障单不再有效时,我会从地图中删除密钥和值(人员和故障单)。

然后,某人可以购买另一张票,此时我会创建一个新的Key + Value。如果一个人仍然在我的HashMap中(但没有与Ticket相关联)那么我可以找到Key(Person)并添加一个新的Value(Ticket),我会比删除它们更有效,然后重新添加他们每次想要购买机票?

btw门票是可变的,所以他们为什么重视我的价值观。人是不可改变的。

7 个答案:

答案 0 :(得分:1)

  

希望它会回归:

one 1 two 2 three

每个地图条目都有一个键和一个值。您希望地图只有一个键但没有"three"键的值,这是不可能的。但是,您可以将null与密钥相关联:

one 1 two 2 three null
  

如果一个人仍然在我的HashMap中(但没有与Ticket相关联),那么我可以找到Key(Person)并添加一个新的Value(Ticket),我会比删除它更有效,然后每次想要购买机票时重新添加它们?

这是一种微观优化,会产生比解决更多的问题,因为没有票的人可能会以两种不同的方式表示:

  • 地图上没有此人的条目,或
  • 地图的条目恰好是null

这很危险,因为您将不可避免地忘记检查null的罚单。即使你不立即这样做,你也可以在六个月内完成。如果你在六个月内没有这样做,那么一旦你接触到你的代码,那么在你之后维护你的程序的人就会犯这个错误。

此外,它会产生“延迟”键的问题:现在地图是单行道,一旦键进入,它就永远停留在那里。这会减慢地图搜索速度,并防止未使用的密钥对象被垃圾回收。

这就是为什么你最好直接删除这个条目,并在你必须这样做的时候重新创建它。

答案 1 :(得分:1)

你得到的原因:

  

1 1 2 2

是因为地图是键值对。想一想:

  

[one,1] [two,2]

每个“[]”之间是一对,需要彼此成为地图的一部分。 我觉得好像在这种情况下使用地图是一种不好的做法。


如果我可以提出替代方案;我可能会创建一个Person对象来保存票证的值。这样你就可以拥有一组Person个对象。

例如:

List<Person> people = new ArrayList<Person>();

String ticket = people.get(0).getTicket();

String newTicket = "2"

people.get(1).setTicket(newTicket);

通过这种方式,您可以使用getter和setter更改和删除票证,并具有良好的面向对象设计。

答案 2 :(得分:0)

试 map.put(“three”,“”); 要么 map.put(“three”,null);

答案 3 :(得分:0)

当值替换为null值时。但是你必须小心,因为NullPointerException。

HashMap<String, String> map = new HashMap<String, String>();

map.put("one", "1");
map.put("two", "2");
map.put("three", "3");

然后只替换

map.put("three", null);

答案 4 :(得分:0)

您可以将密钥与null关联,或者使用某些特殊值&#34; Ticket.invalid()&#34;或类似的东西。但我真的不认为它会对表现做任何事情。我只是删除,然后再添加。代码将更加清晰,这非常重要。 :)

答案 5 :(得分:0)

您可以使用null或空字符串替换故障单值。

但是这里的低效操作正在消除价值。 get中的操作removeputHashMap O (1),因为它们可以使用散列键进行散列。相反,从HashMap删除 O (n),因为它必须扫描所有条目以查找要删除的值。

要删除故障单值,只需通过密钥删除此人。使用put稍后将此人添加回地图效率很高。

如果您必须直接删除票证值,请考虑使用票证值键入的其他HashMap

答案 6 :(得分:0)

您可能需要创建自己的方法。

public static void removeValue(HashMap<String, String> map, String value)
{
    if(map.containsValue(value))
    {
        String key = getKeyByValue(map, value);
        map.put(key, "");
    }
}

public static String getKeyByValue(Map<String, String> map, String value) 
{
    for (Map.Entry<String, String> entry : map.entrySet()) 
    {
        if (value.equals(entry.getValue())) 
        {
            return entry.getKey();
        }
    }
    return "";
}

然后你会像这样实现它:

HashMap<String, String> map = new HashMap<String, String>();

map.put("one", "1");
map.put("two", "2");
map.put("three", "3");

removeValue(map, "3");

for(String name: map.keySet())
{
    String key = name;
    String value = map.get(name);
    System.out.println(key + " " + value);  
}