Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 465
  • Last Modified:

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,
0
Tolgar
Asked:
Tolgar
1 Solution
 
dpearsonCommented:
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
0
 
ManishLeadCommented:
Put comma separated value.
like
name = firstvalue, secondvalue.
eg.
map.put("name", "firstvalue, secondvalue") ;


Get the "name" value from map and add ,secondValue.
0
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
Ahh, you shouldn't even be using a Map at all. You only ever have one item in the map, so it is a bit of a waste to have a whole Map. And your code then iterates over the .keySet() of the Map which will only ever be the one key anyway. So, forget about a Map...

What you need to do is to create a small Class to hold one instance of row which contains "id", "name" and "type". Something like this...
public class CheckDetail {
    private Integer id;
    private String name;
    private String type;

    public CheckDetail(Integer id, String name, String type) {
        this.id = id;
        this.name = name;
        this.type = type;
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getType() {
        return type;
    }
}

Open in new window

Now your database code looks something like...
    public List<CheckDetail> 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`, `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));
        }
        rs.close();
        stmt.close();
        conn.close();
        //System.out.println("checkList:" + checkList);
        return checkList;
    }

Open in new window

And then the code that uses the returned list is quite a bit simpler, as...
            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<CheckDetail> checkListIter = checkList.iterator();
            while(checkListIter.hasNext()) {
              CheckDetail checkDetail = checkListIter.next();

              if (checkDetail.getType().equals("Cpp")){
                TreeItem item_MtCppSubstandards = new TreeItem(item_MtCppStandards, SWT.NONE);
                item_MtCppSubstandards.setText(checkDetail.getName());
              } else if (checkDetail.getType().equals("Java")){
                TreeItem item_MtJavaSubstandards = new TreeItem(item_MtJavaStandards, SWT.NONE);
                item_MtJavaSubstandards.setText(checkDetail.getName());
              } else {
                 TreeItem item_MtOtherSubstandards = new TreeItem(item_MtOtherStandards, SWT.NONE);
                item_MtOtherSubstandards.setText(checkDetail.getName());
              }
            }

Open in new window

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
TolgarAuthor Commented:
@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?
0
 
TolgarAuthor Commented:
Any ideas?
0
 
TolgarAuthor Commented:
Ok. problem solved :)
0
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
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>
0
 
TolgarAuthor Commented:
Thanks!
0
 
mccarlIT Business Systems Analyst / Software DeveloperCommented:
No problem! :)
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now