Link to home
Start Free TrialLog in
Avatar of Tolgar
Tolgar

asked on

How to keep two values under the same key in a hashmap in JAVA?

Hi,
I have a Java code which I read some data from a database. My code works fine but as of now, I only have one value for each key in the hashmap that I have below.

However, I now need to keep two values that corresponds to the same key in the hashmap.

My current code to read data from the database is like this:

    public List<HashMap<Integer, String>> getFullCheckList() throws ClassNotFoundException, SQLException{
        Class.forName("com.mysql.jdbc.Driver") ;
        Connection conn = DriverManager.getConnection("jdbc:mysql://SOMEDATABASE", "SOMEDATABASENAME", "SOMEPASSWORD") ;
        Statement stmt = conn.createStatement() ;
        String queryMtcheckName = "SELECT `name`, `id` FROM `mtcheck`" ;
        ResultSet rs = stmt.executeQuery(queryMtcheckName) ;
        ArrayList<HashMap<Integer, String>> checkList = new ArrayList<HashMap<Integer, String>>();
        while(rs.next()) {
            //System.out.println("rs: " + rs);
            HashMap<Integer, String> check = new HashMap<Integer, String>();
            Integer anId = rs.getInt("Id");
            String aName = rs.getString("Name");
            //System.out.println("anId : " + anId );
            //System.out.println("aName : " + aName );
            check.put(anId , aName );  //I NEED TO PUT ONE MORE VALUE THAT CORRESPONDS TO THE SAME KEY IN HERE WHICH I WILL GET BY aType = rs.getString("Type")
            //System.out.println("check: " + rs);
            checkList.add(check);
        }
        rs.close();
        stmt.close();
        conn.close();
        //System.out.println("checkList:" + checkList);
        return checkList;
    }

Open in new window


In addition to "Name", I now want to get the "Type" from "rs" as the following and I want to put this other value, which is a "Type", that corresponds to the same key with the "Name" value:

String aType = rs.getString("Type");

Open in new window


Basically, I need to save two values for one key.

And then I pass this "checkList" to another class and I do this operation:

            item_MtStandards = new TreeItem(tree, SWT.NONE);
            item_MtStandards.setText("MtStandards");
            
            Iterator<HashMap<Integer, String>> checkListIter = checkList.iterator();
            while(checkListIter.hasNext()) {
              HashMap<Integer, String> amap =   (HashMap<Integer, String>) checkListIter .next();
              Set<?> keysetString = (Set<?>) amap .keySet();
              Iterator<?> iter = keysetString.iterator();
              while( iter.hasNext() ) {
                Integer keyVal = (Integer) iter.next();
                //System.out.println("keyVal " + keyVal);
                String valFromKey = amap.get(keyVal);
                //System.out.println("valFromKey " + valFromKey);
                TreeItem item_MtSubstandards = new TreeItem(item_MtStandards, SWT.NONE);
                item_MtSubstandards.setText(valFromKey);
              } 
            }

Open in new window


I want to change this code as the following so that I will be able to use the "Type" as the control value and the "Name" as the actual value to be set for the text:

            item_MtCppStandards = new TreeItem(tree, SWT.NONE);
            item_MtCppStandards.setText("CppStandards");

            item_MtJavaStandards = new TreeItem(tree, SWT.NONE);
            item_MtJavaStandards.setText("JavaStandards");

            item_MtOtherStandards = new TreeItem(tree, SWT.NONE);
            item_MtOtherStandards.setText("OtherStandards");
            
            Iterator<HashMap<Integer, String>> checkListIter = checkList.iterator();
            while(checkListIter.hasNext()) {
              HashMap<Integer, String> amap =   (HashMap<Integer, String>) checkListIter .next();
              Set<?> keysetString = (Set<?>) amap .keySet();
              Iterator<?> iter = keysetString.iterator();
              while( iter.hasNext() ) {
                Integer keyVal = (Integer) iter.next();
                //System.out.println("keyVal " + keyVal);
                String val1FromKey = amap.get(keyVal); //THIS IS SUPPOSED TO GIVE ME THE "Type"
                String val2FromKey = amap.get(keyVal); //THIS IS SUPPOSED TO GIVE ME THE "Name"
                //System.out.println("valFromKey " + valFromKey);
                if (val1FromKey.equals("Cpp")){
                TreeItem item_MtCppSubstandards = new TreeItem(item_MtCppStandards, SWT.NONE);
                item_MtCppSubstandards.setText(val2FromKey );
} else if (val1FromKey.equals("Java")){
                TreeItem item_MtJavaSubstandards = new TreeItem(item_MtJavaStandards, SWT.NONE);
                item_MtJavaSubstandards.setText(val2FromKey );
              }else {
                 TreeItem item_MtOtherSubstandards = new TreeItem(item_MtOtherStandards, SWT.NONE);
                item_MtOtherSubstandards.setText(val2FromKey );
              }
              } 
            }

Open in new window



So, my main questions are:
- how to keep two values for one key?
- how to get these two values separately by using the corresponding key?

Thanks,
Avatar of dpearson
dpearson

I think you want to use a Map of Maps.

Map<Integer, Map<String, String>> multiMap ;

So each row in the database is itself a map:

Map<String, String> rowMap ;
rowMap.put("name", name) ;
rowMap.put("type", type) ;

and then you put that into the main map:
multiMap.put(key, rowMap) ;

So to get back the name from a given key it's
String name = multiMap.get(key).get("name") ;

And similarly for the type:
String type = multiMap.get(key).get("type") ;

Doug
Put comma separated value.
like
name = firstvalue, secondvalue.
eg.
map.put("name", "firstvalue, secondvalue") ;


Get the "name" value from map and add ,secondValue.
ASKER CERTIFIED SOLUTION
Avatar of mccarl
mccarl
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Tolgar

ASKER

@mccarl: This is exactly what I want but I forgot to tell you something in my first post.

I am now reading from the "results" table in the database.

This results table has 6 columns and plus one id column. The names of these columns in the results table are:

author_id
cat_id
cls_id
filetype_id
mtcheck_id
tm_id

Open in new window


The first id column has the name "id".

The 6 columns all have some ids that refer to other tables in the database.

These 6 tables only have "id" and "name" columns.

So, the following part of my code should be slightly different:

      String queryMtcheckName = "SELECT `name`, `id`, `type` FROM `mtcheck`" ;
        ResultSet rs = stmt.executeQuery(queryMtcheckName) ;
        List<CheckDetail> checkList = new ArrayList<CheckDetail>();
        while(rs.next()) {
            //System.out.println("rs: " + rs);
            Integer anId = rs.getInt("Id");
            String aName = rs.getString("Name");
            String aType = rs.getString("Type");
            //System.out.println("anId : " + anId );
            //System.out.println("aName : " + aName );
            //System.out.println("aType : " + aType );
            checkList.add(new CheckDetail(anId, aName, aType));
        }

Open in new window


So, I need the actual values that the ids in these 6 columns in the results table refer in other tables.

I think the above code should be something like this but I have some missing parts in the code where I explained in the comments:
String queryResults = "SELECT `mtcheck_id`, `filetype_id` FROM `results`" ;
ResultSet rs = stmt.executeQuery(queryResults ) ;
List<CheckDetail> checkList = new ArrayList<CheckDetail>();
String acheckName;
String afiletypeName;
        while(rs.next()) {
           Integer anId = rs.getInt("id");   //id from the results table

           Integer acheckId = rs.getInt("Id of mtcheck in the results table in here");
           String querymtcheck = "SELECT `name`, WHERE `id == acheckId` FROM `mtcheck`" ;

            ResultSet rs2 = stmt.executeQuery(querymtcheck ) ;

             while(rs2.next()) {    //I may not even need to have while in here because ids are unique and I guess there will be only one result in the resultset
             // This table has only id and name columns
              acheckName = rs2.getString("Name");           
            }

           Integer afileTypeId = rs.getInt("Id of filetype in the results table in here");
           String querymtcheck = "SELECT `name`, WHERE `id == afileTypeId ` FROM `filetype`" ;

          ResultSet rs3 = stmt.executeQuery(querymtcheck ) ;

           while(rs3.next){ //I may not even need to have while in here because ids are unique and I guess there will be only one result in the resultset
              afiletypeName = rs2.getString("Name");
          }  
       checkList.add(new CheckDetail(anId, acheckName, afiletypeName ));
       }

Open in new window


And,

But I am not sure how I should do it? Can you please help me with that code?
Avatar of Tolgar

ASKER

Any ideas?
Avatar of Tolgar

ASKER

Ok. problem solved :)
I'm glad you solved it ;) but I hope you didn't solve it in code, like you posted above?

To do what you want, you should make the database do all the hard work. So instead of running 1 query to get all the id's and then running 2 queries for each row returned by the first, you can do it all with just 1 query for the whole thing. The query would be something like this (It looks as though you are using mysql which I'm not 100% across, but I'm pretty sure this should be the right syntax, it'll give you the idea anyway)...
SELECT id, m.name AS name, f.name AS type FROM results r, mtcheck m, filetype f WHERE r.mtcheck_id = m.id AND r.filetype_id = f.id

Open in new window

And then you should be able to use the code that I posted before to collect the data from the rows from this query and build the List<CheckDetail>
Avatar of Tolgar

ASKER

Thanks!
No problem! :)