-2

I have the following Hashmap:

Map<String,String> studentGrades = new HashMap<>();
studentGrades.put("Tom", "A+");
studentGrades.put("Jack", "B+");

Iterator<Map.Entry<String,String>> iterator = studentGrades.entrySet().iterator();
while (iterator.hasNext()) {
    Map.Entry<String,String> studentEntry = iterator.next();
    System.out.println(studentEntry.getKey() + " :: " + studentEntry.getValue());
    iterator.remove();
}

I thought the iterator.remove(); meant that something would be removed from the HashMap, for example iterator.remove("Tom");, then when the iteration happens this is removed from the HashMap.

The program compiles and runs correctly when there iterator.remove(); but when it is iterator.remove("Tom"); an error is found. The compiler says

required: no arguments and found: java.lang.String reason: actual and formal arguments list differ in length.

Any reason why this is happening or have I got iterator.remove(); completely wrong?

Pshemo
  • 122,468
  • 25
  • 185
  • 269
Samual
  • 3
  • 6
  • 1
    You can't pass a String to the remove method because it doesn't work that way. Read up on the Javadocs of Iterator to understand how it works. – Kon Jun 16 '15 at 21:15
  • What can be passed to a remove method? – Samual Jun 16 '15 at 21:24
  • well the answers are pretty much understandable , and also its a not a good idea to remove an entity from a list or whatever dataset you want , while looping in it. – AntJavaDev Jun 16 '15 at 21:30
  • I was just doing it as a way, to display all of the results (and iterate them) and whilst they are iterating, to remove one and then display the new results in the same loop – Samual Jun 16 '15 at 21:39
  • AntJavaDev the `Iterator.remove()` method/API is exactly meant for removing entities while iterating. Filtering data is a common use case. – Has QUIT--Anony-Mousse Jun 18 '15 at 06:24

2 Answers2

1

Per the JavaSE 7 JavaDoc, the remove method for Iterator:

Removes from the underlying collection the last element returned by this iterator (optional operation).

It removes the current element from the collection and "can be called only once per call to next()". It runs against the current value from the iteration and takes no arguments. It's also optional and I'm not certain what all you'd gain by your example. You should be fine without it.

As an aside: I would recommend, as you're iterating a HashMap that perhaps you try the for-in approach, as such:

public static void main(String[] args) {
    HashMap<String, String> studentGrades = new HashMap<String, String>();
    studentGrades.put("Tom", "A+");
    studentGrades.put("Jack", "B+");

    for( Map.Entry<String, String> studentEntry : studentGrades.entrySet() ){
        System.out.println(studentEntry.getKey() +" :: "+ studentEntry.getValue());
    }
}


UPDATE (per comment thread): As an aside, I gave this a go and it worked correctly, outputting without error. If you're dead set on using a java.util.Iterator with the Iterator's next remove method, this should work. I tested it in a scrapbook page for convenience.
public static void main(String[] args) {
    HashMap<String,String> studentGrades = new HashMap<String, String>();
    studentGrades.put("Tom", "A+");
    studentGrades.put("Jack", "B+");

    Iterator<Map.Entry<String,String>> iterator = studentGrades.entrySet().iterator();
    while (iterator.hasNext()) {
        Map.Entry<String,String> studentEntry = iterator.next();
        System.out.println(studentEntry.getKey() + " :: " + studentEntry.getValue());
        iterator.remove();
    }
}
Eric McCormick
  • 2,716
  • 2
  • 19
  • 37
  • Thank you for your detailed help. I have tried that but get an error with studentGrades.entry() ) saying that the method entry is not found – Samual Jun 16 '15 at 21:28
  • That's because I had a typo and forgot to put _entrySet()_ instead of _entry()_. It's updated. Basically, you can (more directly?) iterate just the Map Entry pairs instead of creating an iterator. We can do the same with less lines of code. Here's [a decent link on the Map Interface](https://docs.oracle.com/javase/tutorial/collections/interfaces/map.html) (as opposed to Collection, Set, etc.). – Eric McCormick Jun 16 '15 at 21:29
  • Thank you again, the entrySet() has come up with an error saying incompatible types (the brackets) – Samual Jun 16 '15 at 21:33
  • Yeah, when I updated my example, I set the type where you define the HashMap; you can remove it if you like. – Eric McCormick Jun 16 '15 at 21:36
  • I am quite new to Java so I don't really know what that means sorry – Samual Jun 16 '15 at 21:38
  • Your HashMap can be generic, or you can enforce its type; so _HashMap_ would only allow String keys and String values, for instance. Hang in there, it's a worthwhile language. – Eric McCormick Jun 16 '15 at 21:39
  • Thank you for your help it has been very useful, it is now working. One last question - why do you recommend the for loop instead of while? and is there a way to remove an entry from the HashMap whilst the iteration is happening (for example if there are 4 entries and remove the second one) – Samual Jun 16 '15 at 21:43
  • Is there a particular reason you want or need to remove each entry from the HashMap as you go? [Java has automatic garbage collection](http://stackoverflow.com/a/2263526), so unless you persist the object, it'll eventually take care of itself. – Eric McCormick Jun 16 '15 at 22:03
  • was just doing it as a way, to display all of the results (and iterate them) and whilst they are iterating, to remove one and then display the new results in the same loop – Samual Jun 16 '15 at 22:13
  • Well, I know you _can_ use the remove with an Iterator, I just haven't had need to and was curious as to the use case. – Eric McCormick Jun 17 '15 at 02:08
0

There are two methods named remove in different classes/interfaces.

  1. Iterator's remove() removes the previous item returned.

  2. Collection's remove(object) removes a specific object from a collection

Only the second has a object parameter. But beware: using it invalidates iterators, so don't call it from a loop over the same collection, it will not work. For filtering, use an iterator (like you do), and its remove() method.

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
  • Thanks for your help. So within my Iterator code, where would I place Iterator remove to remove a specific key? – Samual Jun 16 '15 at 21:23
  • [`Map`](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html) is not [`Collection`](https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html) (at least not in inheritance way). Collections have `remove(element)` maps have `remove(key)`, so consider changing `Collection` to `Map`. – Pshemo Jun 16 '15 at 21:29
  • within my Iterator code, where would I place Iterator remove to remove a specific key? – Samual Jun 16 '15 at 21:41
  • Put an `if` around your `remove()`... and read the documentation of `Iterator`! – Has QUIT--Anony-Mousse Jun 16 '15 at 22:25