Results 1 to 8 of 8
  1. #1
    Paul Richards is offline Member
    Join Date
    Oct 2008
    Location
    UK
    Posts
    65
    Rep Power
    0

    Default LinkedHashMap insertion whilst iterating

    I wrote a class with a LinkedHashMap that I iterate over whilst inserting new elements. Here is a simplified example:

    Java Code:
    LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
    Iterator<Entry<Integer, String>> iterator = map.entrySet().iterator();
    map.put(666, "test");
    System.out.println(iterator.hasNext());
    The result is: false. If you swap the 2nd and 3rd lines though, its true.

    I did an experiment with LinkedList and the problem does not occur here; the result is true whether the iterator was created before or after the call to put.

    Perhaps the entrySet() method gets a copy of the data, as it is at that time. so when you add new data its result is unaffected.

    So, it looks like I am going to have to use another data structure!

  2. #2
    wolfcro is offline Member
    Join Date
    Feb 2009
    Location
    Italy
    Posts
    51
    Rep Power
    0

    Default

    if you read the javadoc for HashMap

    HashMap (Java Platform SE 6)

    you clearly see the part of the entrySet() method that interest you:

    The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll and clear operations. It does not support the add or addAll operations.

  3. #3
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    Wolfcro is right, and note you must use the *iterator* methods. Once you get an iterator, you can not externally mess with the map. It can produce some sort of external modification exception.

    I suggest rethinking your logic. Why are you getting an iterator, then modifying the map, then iterating?

  4. #4
    Paul Richards is offline Member
    Join Date
    Oct 2008
    Location
    UK
    Posts
    65
    Rep Power
    0

    Default

    Thanks wolfcro and steve, I never thought at looking at the javadoc, that should have been my first step really.

    My logic is sound, its what I need to do. I have some things which I want to store in an order, and as they are worked through they generate some more things of the same type that have to be stored. It is like a map, because the things are in two halves (like a key/value). Delete and external random access is not required. I need to be able to:
    • insert/modify; this is one operation which either inserts or modifies, like the put method in maps
    • get the value, given the key
    • traverse the list; the object itself needs to keep track of the position in the list of the current item


    I think I am going to use some sort of list, with an int variable as a pointer to the current item.

  5. #5
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    Paul -- it usually doesn't so make sense to require your logic to insert while you're iterating through the map, because with a map generally (even though you're using a LinkedHashMap here) there's no logical answer to the question of "what position in the iteration does item X come?". Does it break your logic to make your insertions to a NEW map while iterating through, then do an addAll() at the end? (Bearing in mind that an insertion into the new map of mapping to an existing key will translate into a modification when you do the addAll().)
    Last edited by neilcoffey; 02-12-2009 at 10:44 PM. Reason: added clarification

  6. #6
    Paul Richards is offline Member
    Join Date
    Oct 2008
    Location
    UK
    Posts
    65
    Rep Power
    0

    Default

    neil, it does break the logic. As the items are read, they cause more to be added to the end of the list. It is more like a list than a map, and so that is why I will use a list.

    I thought that LinkedHashMap was what I needed - it combines begin able to order the items with the convenience of being able to look up a value from a key. However, the latter can be achieved with my own methods simply by iterating through the list. There won't be many items so efficiency is not a huge issue.

  7. #7
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    Ah I see -- yes unfortunately in this case, I think you'll have to have a separate list as you say.

  8. #8
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    Neil's two list approach makes sense, given that you are iterating and adding.

    To gain the desired effect, you could have two working maps (yes, I know).

    Iterate over the main map, add to workmap1.

    Iterate over workmap1, add to workmap2. Merge workmap1 to the main map. Clear workmap1. Swap workmap1 and workmap2.

    Repeat the last step until workmap2 is empty.

    The advantage of that logic is that it uses built-in collections, and the logic flow clearly portrays the purpose behind the logic.

Similar Threads

  1. Regarding Data Insertion
    By adeeb in forum JDBC
    Replies: 1
    Last Post: 06-22-2008, 06:26 AM
  2. Using PreparedStatement for insertion
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 02-06-2008, 10:30 AM
  3. database insertion
    By abhiN in forum New To Java
    Replies: 0
    Last Post: 01-17-2008, 08:24 AM
  4. Insertion sort algorithm
    By Albert in forum Advanced Java
    Replies: 2
    Last Post: 06-28-2007, 09:26 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •