39

I have a Hashtable in Java and want to iterate over all the values in the table and delete a particular key-value pair while iterating.

How may this be done?

CJBS
  • 15,147
  • 6
  • 86
  • 135
Mohit BAnsal
  • 1,571
  • 5
  • 16
  • 14

4 Answers4

44

You can use Enumeration:

Hashtable<Integer, String> table = ...

Enumeration<Integer> enumKey = table.keys();
while(enumKey.hasMoreElements()) {
    Integer key = enumKey.nextElement();
    String val = table.get(key);
    if(key==0 && val.equals("0"))
        table.remove(key);
}
mostar
  • 4,723
  • 2
  • 28
  • 45
44

You need to use an explicit java.util.Iterator to iterate over the Map's entry set rather than being able to use the enhanced For-loop syntax available in Java 6. The following example iterates over a Map of Integer, String pairs, removing any entry whose Integer key is null or equals 0.

Map<Integer, String> map = ...

Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();

while (it.hasNext()) {
  Map.Entry<Integer, String> entry = it.next();

  // Remove entry if key is null or equals 0.
  if (entry.getKey() == null || entry.getKey() == 0) {
    it.remove();
  }
}
Adamski
  • 54,009
  • 15
  • 113
  • 152
  • 6
    You can't have `null` keys in a `Hashtable`. That's what makes it different from a `Map`. Also, you're querying `Map.Entry getValue` in the above code, instead of `getKey`. You can't do `entry.getValue() == 0` because the values are of type `String`. – polygenelubricants Feb 28 '10 at 14:55
  • 1
    @polygenelubricants, Map is an interface that makes no restrictions on null. HashMap is a Map implementation that doesn't allow nulls. – Steve Kuo Feb 28 '10 at 16:28
  • 1
    I don't reference Hashtable in my code and would not use it anyway as it's superseded by HashMap (which **does** allow null keys and values). – Adamski Feb 28 '10 at 19:01
  • 1
    BTW 2 downvotes?! Seems like some people are stuck using JDK 1.1 collections or just don't bother reading the API definition of Map. – Adamski Feb 28 '10 at 19:04
  • I mention `Hashtable` because that's what OP has. And @Steve, `HashMap` does allow nulls (http://java.sun.com/javase/6/docs/api/java/util/HashMap.html). – polygenelubricants Feb 28 '10 at 19:14
  • And @Adamski, people are downvoting because the code is wrong. You said your code is supposed to "remove entry if key is null or equals 0", but instead you query `entry.getValue()` (which is of `String` type) instead of `entry.getKey()` (which is of Integer type). – polygenelubricants Feb 28 '10 at 19:20
  • @poly: Fair point and thanks for pointing that out (corrected) but why not just add a comment to that effect rather than downvote (which doesn't help anyone)? – Adamski Feb 28 '10 at 19:45
  • The first comment in this answer is mine, and it said exactly that. As for why people downvote instead of commenting, you have to ask them. – polygenelubricants Feb 28 '10 at 19:51
  • And by the way, the code is still wrong. `getValue()` returns a `String`. A string can't be compared to the number 0. – polygenelubricants Feb 28 '10 at 19:53
7

You can use a temporary deletion list:

List<String> keyList = new ArrayList<String>;

for(Map.Entry<String,String> entry : hashTable){
  if(entry.getValue().equals("delete")) // replace with your own check
    keyList.add(entry.getKey());
}

for(String key : keyList){
  hashTable.remove(key);
}

You can find more information about Hashtable methods in the Java API

Scharrels
  • 3,055
  • 25
  • 31
  • 1
    You can do this but it's not necessary to use an additional collection; It just makes things more complicated. – Adamski Feb 28 '10 at 19:05
7

So you know the key, value pair that you want to delete in advance? It's just much clearer to do this, then:

 table.delete(key);
 for (K key: table.keySet()) {
    // do whatever you need to do with the rest of the keys
 }
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623