CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    May 2002
    Location
    Montreal
    Posts
    450

    HashMap replaces pair key/value, why?

    I am having this problem with a HashMap: when trying to insert a new Long value using a Date as the key, my first or second pair key/value entry gets replaced with the third one even though the key is different.

    Code:
    		for (Iterator iter = psr.getProduction().iterator(); iter.hasNext();)
    		{
    			Object[] current = (Object[]) iter.next();
    
    			Date date = new Date();
    			date.setTime(((Date)current[0]).getTime());
    			
    			log.info("Production=> date: " + date );
    			objectCal.setTime(date);
    			
    			Long qte = (Long) current[1];
    
    			if(date.compareTo(today) < 0 )
    			{
    			    log.info("Production: " + qte + " skipped");			        
    			    continue;
    			}
    
    			log.info("Production=> objectDate: " + objectCal.getTime() + ", Qte: " + qte );
    			log.info("Production=> today: " + today );
    			
    			// If the map already contains the key, add up results.
    			if( entries.containsKey( date ))
    			{
    				Long initial = (Long)entries.get( date );
    				Long sum = new Long( qte.longValue() + initial.longValue() );
    				entries.remove( date );
    				entries.put( date, sum );
    			}
    			else
    				entries.put( date, qte );
    			
    	        log.info("Production: " + qte + " added");
    	        
    		}
    getProduction() is a List. In my problem, it only contains 3 items


    i.e.
    on the first loop, I pass a date, say "Tue Jun 14 00:00:00 EDT 2005" as the key and 45 as a Long value. It is placed in HashMap slot[6] (I can see in the debugger representation of the HashMap)

    In the second loop, I pass the date as 'Wed Jun 15 00:00:00 EDT 2005' with the Long value of 5. It is placed in HashMap slot[2]

    In the third loop, I pass the date as 'Thu Jun 16 00:00:00 EDT 2005' and a value of 5. It is placed in HashMap slot[6].

    The code only runs through the
    entries.put( date, qte ) portion in this example.


    The result is that the third entry totally replaces the first one in the HashMap and I lose the first pair key/value. The indicated size of the HahMap is 2, I can only see the last 2 keys entered even though I only used different keys.

    I tried to use a Hashtable instead of a HashMap, but I get the same problem. I also tried to use date.toString() as a key, same results with different indexes in the HashMap

    Why is that happening? How can I go aroiund it. I need to sorted on the keys later as I am adding to the HashMap from different Lists that may not be in the same date order.
    Last edited by lsmeteor; June 16th, 2005 at 10:21 AM.
    Cheers,
    Laurent

    For an aviator, the three best things in life are a good landing, a good orgasm, and a good sh*t. A night carrier landing is one of the few opportunities to experience all three at the same time.

  2. #2
    Join Date
    Jun 2005
    Location
    Ukraine
    Posts
    45

    Re: HashMap replaces pair key/value, why?

    Hm, it works fine.

    Code:
    public final class Test
    {
        public static void main(String[] args)
        {
            List production = new ArrayList();
            Object[] product1 = {new Date(1), new Long(1)};
            Object[] product2 = {new Date(2), new Long(1)};
            Object[] product3 = {new Date(3), new Long(1)};
    
            production.add(product1);
            production.add(product2);
            production.add(product3);
    
            Map entries = new HashMap();
    
            for (Iterator iter = production.iterator(); iter.hasNext();)
            {
                Object[] current = (Object[]) iter.next();
    
                Date date = new Date();
                date.setTime(((Date)current[0]).getTime());
    
                Long qte = (Long) current[1];
    
                if( entries.containsKey( date ))
                {
                    Long initial = (Long)entries.get( date );
                    Long sum = new Long( qte.longValue() + initial.longValue() );
                    entries.remove( date );
                    entries.put( date, sum );
                }
                else
                    entries.put( date, qte );
            }
            System.out.println("SIZE: " + entries.size());
        }
    }

  3. #3
    Join Date
    May 2002
    Location
    Montreal
    Posts
    450

    Re: HashMap replaces pair key/value, why?

    Thanks for taking the time to look at it.

    Correction: The indicated size is 3 as expected, but there are only 2 keys since one of them is overwritten. I just can't understand why it shows a size of 3 but can't get to all 3 elements.

    Anyhow, I replaced the HashMap type with a TreeMap, which is sorted and I can get to all elements with no problem. Plus I don't have to extract the keys then sort.

    So a TreeMap it is for now, but I still don't know why the strange behaviour.
    Cheers,
    Laurent

    For an aviator, the three best things in life are a good landing, a good orgasm, and a good sh*t. A night carrier landing is one of the few opportunities to experience all three at the same time.

  4. #4
    Join Date
    Jun 2005
    Posts
    3

    Re: HashMap replaces pair key/value, why?

    Maybe the two keys hash to the same hash value?

  5. #5
    Join Date
    May 2002
    Location
    Montreal
    Posts
    450

    Re: HashMap replaces pair key/value, why?

    I thought about that too.
    I put in the following code to check:

    log.info("date hashcode: " + date + " : " + date.hashCode());

    and the code is different for each date.
    1. 2030103300
    2. 2116503300
    3. -2092063996


    The last item overwrites the first item.
    There must be because of something else. Go figure.
    I am now using a TreeMap and I don't experience the problem. The rest of the code is the same.
    Cheers,
    Laurent

    For an aviator, the three best things in life are a good landing, a good orgasm, and a good sh*t. A night carrier landing is one of the few opportunities to experience all three at the same time.

  6. #6
    Join Date
    Jun 2005
    Location
    Ukraine
    Posts
    45

    Re: HashMap replaces pair key/value, why?

    It's mistic

    I think you need to apply for information to SUN

  7. #7
    Join Date
    Feb 2004
    Location
    USA - Florida
    Posts
    729

    Re: HashMap replaces pair key/value, why?

    Are you saying you add 3 items to the HashMap and can only examine 2 when you iterate through it? Or are you just basing this on what the debugger is showing you?

    If it's the first one, then please post compilable code that can reproduce this problem, if you can't, then it means the problem is elsewhere.

    If it's the second one, then it's an implementation detail. Inferring from HashMap's javadoc, it use's a separate-chaining-hashtable implementation. What this simply means is that each element in the array contains a list, and if 2+ items hash to the same hashcode, the list at the appropriate array position is updated. A simple java applet showing how this works can be found here: http://mainline.brynmawr.edu/Courses...HashChain.html
    Hungarian notation, reinterpreted? http://www.joelonsoftware.com/articles/Wrong.html

  8. #8
    Join Date
    May 2002
    Location
    Montreal
    Posts
    450

    Re: HashMap replaces pair key/value, why?

    It was more like the first case. I would only be able to access 2 of the 3 items entered. The debugger would confirm what the code was about to do. I was logging the iteration and one item was indeed missing at the end.

    I am not sure if I could recreate the same behaviour as the very same code exists in another part of the project and works very well.
    I don't know why the above behaviour happened but using a treeMap solved my problem for now. As I am on deadline, I won't spend more time trying to figure out why, there may be too many variables and I'll just consider this as a freak occurence until it happens again.

    Thanks all for your help
    Cheers,
    Laurent

    For an aviator, the three best things in life are a good landing, a good orgasm, and a good sh*t. A night carrier landing is one of the few opportunities to experience all three at the same time.

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured