[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

HashMap: new Map Value overwrites pre-existing map value

Posted on 2006-05-23
20
Medium Priority
?
504 Views
Last Modified: 2010-05-18
Hello,

HashMap Question:  I have a HM w/ 3 Parms:  
1) PO_NUMBER
2) PR_NUMBER
3) LINE_NUMBER

I pass this into a few private methods (from a 'controller'method.)  No modifications.

Then, If a certain condition is met, I want to add a new Map Value to the HashMap:  CREATIONDATE.

I am seeing CREATIONDATE overwrite LINE_NUMBER.

Why?
Is there something else I should look for?
0
Comment
Question by:fshtank
  • 7
  • 4
  • 4
  • +2
20 Comments
 

Author Comment

by:fshtank
ID: 16747707
An additional fact I've come across:

I tried 2 things:
1) Create a new HashMap and move all the values over to it from the original, then add CREATIONDATE.
    Result:  CREATIONDATE still steps on LINE_NUMBER,

2) Change the order of adding map values:
    - Add CREATIONDATE
    - then add LINE_NUMBER
    Result: LINE_NUMBER steps on CREATIONDATE and overwrites it.

This doesn't make sense.

Thanks for your help.
0
 
LVL 3

Expert Comment

by:Krule
ID: 16748017
Some code would definately help here. Can you post the code that creates your hashmap, as well as the one that adds values to it?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16748811
You don't say what the keys and values are in the Map. A Map cannot contain duplicate keys, so if LINE_NUMBER somehow equals CREATION_DATE, then the earlier key will be replaced by the later one
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 92

Expert Comment

by:objects
ID: 16748867
> I want to add a new Map Value to the HashMap:  CREATIONDATE.
> I am seeing CREATIONDATE overwrite LINE_NUMBER.

You need to add LINE_NUMBER with a different *key*

map.put("CREATIONDATE", myCreationDate);
map.put("LINE_NUMBER", myLineNumber);

0
 
LVL 4

Expert Comment

by:fffej78
ID: 16749290
If the keys are LINE_NUMBER and CREATION_DATE and these are objects of your own doing, then you need to ensure that the hashCode and equals methods on them are implemented correctly.

It's non-trivial to get this right, so I recommend reading http://www-128.ibm.com/developerworks/java/library/j-jtp05273.html for more information.
0
 

Author Comment

by:fshtank
ID: 16754118
Hello everyone and thanks for the responses:

Here is the relevant code:

MAP KEYS ARE:
- PO_NUMBER   (String)
- PR_NUMBER   (String)
- LINE_NUMBER   (String)
- ** I want to later add  CREATIONDATE   (java.sql.Date)

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CODE   CODE   CODE  CODE  CODE   CODE  CODE  CODE   CODE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  // Map params is the incoming HashMap  (unmodified)

  public DetailLotChargeTO[] getDetailLotCharges( Map params )  throws RuntimeException
  {  
      HashMap             histMap = null;
      Date                   maxDt = null;   // NOTE :: java.sql.Date
     

          // Call _Aggregate to see if GT Zero, using HM  params
          // ... HM is only read, not updated.

          if (this.getDetailLotCharge_Aggregate(params) > 0) {
             
             maxDt = this.getDetailLotChargeHistory_CreationDate(params);   // ... HM 'params' is only read, not updated.

                 histMap = new HashMap();  // Re-use Map to send to _History
                 
                 histMap.put(CREATIONDATE, (Date) params.get( CREATIONDATE ) );
                 histMap.put(PR_NUMBER, (String)params.get( PR_NUMBER ) );
                 histMap.put(PO_NUMBER, (String)params.get( PO_NUMBER ) );
                 histMap.put(PO_NUMBER, (String)params.get( LINE_NUMBER ) );
             
             
             dto = this.getDetailLotCharges_History( histMap );       // 'dto' is an array of a class DetailLotChargeTO[]
          }
      }
     
      return dto;        // 'dto' is an array of a class DetailLotChargeTO[]  ... see above
  }

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

CREATIONDATE before  LINE_NUMBER  overwrites LINE_NUMBER.
LINE_NUMBER   before  CREATIONDATE  overwrites  CREATIONDATE

The capitalized letters are the key.

It seems crazy, but I am watching it happen in Debug.  

Thanks.
0
 
LVL 4

Expert Comment

by:fffej78
ID: 16754156
The following two lines are a bit daft:

histMap.put(PO_NUMBER, (String)params.get( PO_NUMBER ) );
histMap.put(PO_NUMBER, (String)params.get( LINE_NUMBER ) );

This is overwriting entries in the map. (a map is a one to one relation).  Are you sure PO_NUMBER and PR_NUMBER are different strings as well?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16754214
Your keys are the same as the values, so your Map is redundant. You may as well use a List. Then you *can* have duplicates
0
 
LVL 3

Expert Comment

by:Krule
ID: 16754839
this:
                 histMap.put(CREATIONDATE, (Date) params.get( CREATIONDATE ) );
                 histMap.put(PR_NUMBER, (String)params.get( PR_NUMBER ) );
                 histMap.put(PO_NUMBER, (String)params.get( PO_NUMBER ) );
                 histMap.put(PO_NUMBER, (String)params.get( LINE_NUMBER ) );
             
looks like it should read like this:

                 histMap.put(CREATIONDATE, (Date) params.get( CREATIONDATE ) );
                 histMap.put(PR_NUMBER, (String)params.get( PR_NUMBER ) );
                 histMap.put(PO_NUMBER, (String)params.get( PO_NUMBER ) );
                 histMap.put(LINE_NUMBER, (String)params.get( LINE_NUMBER ) );

0
 
LVL 4

Expert Comment

by:fffej78
ID: 16754946
Doesn't that mean you are copying the map?

Wouldn't histMap = new HashMap( params ) have exactly the same effect? (if there isn't a copy constructor then you catch my drift anyway I'm sure)
0
 
LVL 3

Assisted Solution

by:Krule
Krule earned 200 total points
ID: 16755004
Thats a good point, this is a map to map copy, what is the purpose? Is it that you dont want the other entries that exist in the other map? If thats the case, I suppose this is a good solution.
0
 

Author Comment

by:fshtank
ID: 16755723

You guys are correct.  My Type-o.  Sorry.
The source code is actually how you laid it out:

                 histMap.put(CREATIONDATE, (Date) params.get( CREATIONDATE ) );
                 histMap.put(PR_NUMBER, (String)params.get( PR_NUMBER ) );
                 histMap.put(PO_NUMBER, (String)params.get( PO_NUMBER ) );
                 histMap.put(LINE_NUMBER, (String)params.get( LINE_NUMBER ) );

I messed up in translation.

I forgot to mention, there is an inteface with constants (Capitalized keys above) with a string value which matches the above.
So PO_NUMBER = "PO_NUMBER", PR_NUMBER="PR_NUMBER" etc.


Lastly, the reason I physically copied from one map value at a time  was to watch the interaction in code.

I originally wasn't even going to use  'histMap'  but  adding a value (CREATIONDATE) in 'params'  kept stepping on LINE_NUMBER and I wanted to watch the interaction.

0
 

Author Comment

by:fshtank
ID: 16755735
 PS, and moving CREATIONDATE to the top I can watch it step on the LINE_NUMBER parameter.
 
 
0
 
LVL 4

Assisted Solution

by:fffej78
fffej78 earned 200 total points
ID: 16755794
As previously said, the only way that a value can step on something in a map, is if they have the same hashCode.  Can you post the interface with the constants in?  It must have duplicated values in it, or something similar.
0
 

Author Comment

by:fshtank
ID: 16756090
Here you Go - - the Constants interface:



::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
package com.company.app.dao.orcl.constants;

import com.company.app.transfer.DetailLotChargeTO;

public interface MiscConstants {
    /**
     * Maps to DOUBLE of Amount
     */
    public static final String AMOUNT = "AMOUNT_LIST";  // Defect 1623

    /**
     * Maps to ArrayList of amountList (doubles of amount)
     */
    public static final String AMOUNT_LIST = "AMOUNT_LIST";
   
    /**
     * Maps to String of awardCode
     */
    public static final String AWARD_CODE = "AWARD_CODE";

    /**
     * Maps to String of buyerCode
     */
    public static final String BUYER_CODE = "BUYER_CODE";

    /**
     * Maps to String of account
     */
    public static final String CHARGE_NUMBER = "CHARGE_NUMBER";

    /**
     * Maps to String of CHARGE_AMOUNT
     */
    public static final String CHARGE_AMOUNT = "CHARGE_AMOUNT"; // 1623
       
    /**
     * Maps to String of commodityCode
     */
    public static final String COMMODITY_CODE = "COMMODITY_CODE";

    /**
     * Maps to String of COST_EXISTS_FLAG
     */
    public static final String COST_EXISTS_FLAG = "COST_EXISTS_FLAG";   // Defect 1623
   
    /**
     * Maps to Date value CREATIONDATE (MAX or itemized detail)
     */
    public static final String CREATIONDATE = "CREATIONDATE";
   
    /**
     * Maps to String of searchLine
     */
    public static final String DESCRIPTION = "DESCRIPTION";
   
    /**
     * Maps to String "FLAG"
     */
    public static final String FLAG = "FLAG";  // Defect 1623

    /**
     * Maps to String of endUse
     */
    public static final String ENDUSE_CODE = "ENDUSE_CODE";

    /**
     * Maps to String of gla
     */
    public static final String GLA = "GLA";

    /**
     * Maps to String of inventoryDepartment
     */
    public static final String INVENTORY_DEPT = "INVENTORY_DEPT";

    /**
     * Maps to String of lineNo
     */
    public static final String LINE_NUMBER = "LINE_NUMBER";

   
    /**
     * Maps to DetailLotChargeTO[] in parameter map
     */
    public static final String LOT_DETAILS = "LOT_DETAILS";  // Defect 1623

    /**
     * Maps to String in LOT_SIZE value
     */
    public static final String LOT_SIZE = "LOT_SIZE";  // Defect 1623
   

    /**
     * Maps to ArrayList of lotSizeList (Strings of lot size)
     */
    public static final String LOT_SIZE_LIST = "LOT_SIZE_LIST";

    /**
     * Maps to String of pcCode
     */
    public static final String MFG_PC_CODE = "MFG_PC_CODE";

    /**
     * Maps to String of partNo
     */
    public static final String PART_NUMBER = "PART_NUMBER";

    /**
     * Maps to String of poNo
     */
    public static final String PO_NUMBER = "PO_NUMBER";

    /**
     * Maps to String of prNo
     */
    public static final String PR_NUMBER = "PR_NUMBER";

    /**
     * Maps to String of priorityCode
     */
    public static final String PRIORITY_CODE = "PRIORITY_CODE";

    /**
     * Maps to String of project
     */
    public static final String PROJECT = "PROJECT";

    /**
     * Maps to String of routeCode
     */
    public static final String ROUTING_CODE = "ROUTING_CODE";

    /**
     * Maps to String of endRowNo (int)
     */
    public static final String ROW_NUMBER_END = "ROW_NUMBER_END";

    /**
     * Maps to String of startRowNo (int)
     */
    public static final String ROW_NUMBER_START = "ROW_NUMBER_START";

    /**
     * Maps to String of rowid
     */
    public static final String ROWID = "ROWID";

    /**
     * Maps to String of rowids
     */
    public static final String ROWIDS = "ROWIDS";

    /**
     * Maps to String of siteCode
     */
    public static final String SITE_CODE = "SITE_CODE";

    /**
     * Maps to String of sourceCode
     */
    public static final String SOURCE_CODE = "SOURCE_CODE";

    /**
     * Maps to String of supplierCd
     */
    public static final String SUPPLIER_CODE = "SUPPLIER_CODE";

    /**
     * Maps to String of TYPE_OF_COST
     */
    public static final String TYPE_OF_COST = "TYPE_OF_COST";  // Defect 1623
   
   
    /**
     * Maps to ArrayList of typeCostList (Strings of type cost)
     */
    public static final String TYPE_OF_COST_LIST = "TYPE_OF_COST_LIST";

    /**
     * Maps to String of user (int)
     */
    public static final String USER_ID = "USER_ID";

    /**
     * Maps to String of userId
     */
    public static final String USER_IDS = "USER_IDS";
}
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
0
 
LVL 86

Assisted Solution

by:CEHJ
CEHJ earned 800 total points
ID: 16756107
These two are the same, but i don't see them getting used in the Map

public static final String AMOUNT = "AMOUNT_LIST";  // Defect 1623

    /**
     * Maps to ArrayList of amountList (doubles of amount)
     */
    public static final String AMOUNT_LIST = "AMOUNT_LIST";
   
0
 
LVL 92

Accepted Solution

by:
objects earned 800 total points
ID: 16756158
Thats all fine, should not create a problem with the code you have posted.
try prointing out the value of your map before and after adding the values

System.out.println(histMap);
0
 

Author Comment

by:fshtank
ID: 16756702

Aaargh!
OBJECTS:  I should've   'System.out'   the values a long time ago.  I've had tunnel vision with the Eclipse debugger.

CEHJ: you probably saved me another 2 hours of debugging pointing out the AMOUNT / AMOUNT_LIST descrepancy.

          > I split the lion's share of points between you.

fffej78  & KRULE:  I gave you points as well as your ideas led everyone up to this point.  Thanks for your help.  (At least I think EE's interface gave you the points I specified.  Let me know if you didn't get any and I will try to correct it.)

Thanks again.
0
 

Author Comment

by:fshtank
ID: 16756709

I forgot to mention:
-> Eclipse showed the values being overwritten.
-> The System.out showed the values were actually being captured.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16758428
:-)
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
Suggested Courses
Course of the Month18 days, 14 hours left to enroll

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question