Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

HashMaps 3

Status
Not open for further replies.

Elle

Programmer
Sep 19, 2000
20
0
0
GB
Hi Guys,

I'm looking for some information on HashMaps. I have searched the net but i can't find anything easy to understand or any examples of how to use them. Does anyone have any suggestions? My program reads in from a text file, information about which user used the printer, how many pages, which printer was used etc. This info is then parsed by a stringTokenizer line by line and i now need a HashMap to keep a running total of how many pages the user prints off within the file so i can charge them accordingly. Any suggestion of where else to go looking. I have two textbooks but they don't even mention HashMaps.

Cheers
Elle
 
Ok ta, sorry this is probably a really stupid question but i've managed to completely confuse myself.

if i did say
hm.put("username","7");
What does the 7 mean? Which value? The index in the map similar to an array? Or the value of the token from my stringTokenizer? So it looks for the 7th token in the string. And does the key match the exact string? So if i was looking for username bobmcg would i do
hm.put("bobmcg","7"); ?? so does that mean i need to search separately for each user on my system? Thats sounds really wrong? Sorry but it's monday and it's not going well already!
 
>>> hm.put("bobmcg","7");

The key "bobmcg" is used to look up the value "7" - so

System.out.println(hm.get("bobmcg"));

This will retrieve "7"
 
Ok cool, I think i should be able to get moving. Thanks for your help!
 
Hi,
I have anothe hashmap question. Can you store more than one value for each key? For example use recordid as the key and store values pagesprinted, username, printername. As one entry? I tried the normal way of
RecordMap.put = (recordid, pagesprinted, username, printername);

But it produced errors. Is there a way round this or an alternative method?

 
To be honest, it sounds like you need to create your own data object/bean and then store that in a HashMap. Then you caould map lots of data to just one key ...
 
Here's a class I call MultiMap. It stores a List of objects for each key:

public final class MultiMap implements Serializable {
Hashtable _map = new Hashtable();
public void add(Object key, Object value) {
ArrayList values = (ArrayList)_map.get(key);
if (values == null) {
values = new ArrayList();
_map.put(key, values);
}
values.add(value);
return;
}
public List get(Object key) {
Object[] vals = null;
List values = (List)_map.get(key);
return values;

}
public Object remove(String key, Object value) {
Object retvalue = null;
List values = (List)_map.get(key);
if (values != null) {
if (values.remove(value))
retvalue = value;
if (values.isEmpty()) {
_map.remove(key);
}
}
return retvalue;
}
}
 
Ok, thanks guys. Sean with your code how would i send it my values?
 
OK, here is a way which I think is the most OO, and also the tidiest ...

First, you have a data object bean :
Code:
public class MyDataHolder {

   private int intVal = 0;
   private String strVal = "";

    public void setIntVal(int intVal) {
        this.intVal = intVal;
    }

    public int getIntVal() [
        return intVal;
    }
    public void setStrVal(int strVal) {
        this.strVal = strVal;
    }

    public int getStrVal() [
        return strVal;
    }
}

The you populate your MyDataHolder using the setter methods, and then add it to your HashMap :

Code:
HashMap hm = new HashMap();
MyDataHolder mdh = new MyDataHolder();
mdh.setIntVal(555);
mdh.setStrVal("Hello There");

hm.put("myKeyVal999", mdh);

// and to retrieve

 MyDataHolder mdh2 = (MyDataHolder)hm.get("myKeyVal999");
System.err.println(mdh2.getIntVal() +" " +mdh2.getStrVal());
 
Hi,
Cheers i did as instructed but it seems to be giving me an error mesage when i run the code.

java.lang.NullPointerException
at Test.main(Test.java:74)
Exception in thread "main" 

Any ideas where i've gone wrong?
...

Code:
public class Test {
	public static void main(String[] args) throws IOException {             
            
                File output = new File("N:/output.txt");
                FileWriter out = new FileWriter(output);              
                BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File("N:/Printer.txt"))));
		String line = ""; 
                int tokenid = 0;               
                int id = 0;
                String date = "";
                String username = "";
                String printer = "";
                String document = "";
                String pages = "";
                               
                PrintingRecord myrecord = new PrintingRecord(id, date, username, printer, document, pages); 
                
                myrecord.id = 0;
                
                while((line= reader.readLine()) != null) { //Keep on reading in lines until EOF
			System.out.println(line);   //reading in all lines ok
                       StringTokenizer st = new StringTokenizer(line, ",;:");                                           
                                                                  
                       String token;
                       tokenid = 0;
                       myrecord.id++;
                                                                     
                       while(st.hasMoreTokens()){ //while there are still tokens to read                   	                      	
			out.flush();
                                                
                        token = st.nextToken();
                        out.write(token); //output token to file
                        out.write('\n');                      
                                             
                          //assign variables to tokens                     
                        if (tokenid == 0){
                          myrecord.date= token;
                           }
                        
                        if (tokenid == 8){
                          myrecord.username = token;                            
                            }
 
                        if (tokenid == 11){
                          myrecord.printer = token;                            
                            }
                        
                        if (tokenid == 13){
                          myrecord.pages = token;                            
                            }                    
                        
                          tokenid++;                      
                       }
                        
                       System.out.println("Date  " + myrecord.date + "Token ID is  " + tokenid);                                             
                       System.out.println("Username  " + myrecord.username + "Token ID is  " + tokenid);    
                       System.out.println("Printer  " + myrecord.printer + "Token ID is  " + tokenid);
                       System.out.println("RecordID is  " + myrecord.id);   
                       
                       
                      HashMap RecordMap = new HashMap();
                      MyDataHolder mdh = new MyDataHolder();
                      mdh.setIntVal(myrecord.id);
                      mdh.setStrVal(myrecord.username);
                      String myrecordidasString = myrecord.id + "";
                      RecordMap.put(myrecordidasString, mdh);

                      // and to retrieve

                      MyDataHolder mdh2 = (MyDataHolder)RecordMap.get("1");
                      System.err.println(mdh2.getIntVal() +" " + mdh2.getStrVal());
                                                                           
                      
                }
                               
               out.close();                            
	}


   public static class PrintingRecord {
       public PrintingRecord(int id_, String date_, String username_, String printer_, String document_, String pages_){
           id = id_;
           username = username_;
           printer = printer_;
           document = document_;
           pages = pages_;
           
       }
                public int id =0;
                public String date;
                public String username;
                public String printer;
                public String document;
                public String pages;
         
         
   }

public static class MyDataHolder {

   private int intVal = 0;
   private String strVal = "";

    public void setIntVal(int intVal) {
        this.intVal = intVal;
    }

    public int getIntVal() {
        return intVal;
    }
    public void setStrVal(String strVal) {
        this.strVal = strVal;
    }

    public String getStrVal() {
        return strVal;
    }
}
}
 
On the line near the end which is ::

>>> MyDataHolder mdh2 = (MyDataHolder)RecordMap.get("1");

RecordMap.get("1") return as "null" ....

This is because you are looping the input file, and each time creating a new "RecordMap" on this line
>>> HashMap RecordMap = new HashMap();

So on the second loop, you call on this line

>>> MyDataHolder mdh2 = (MyDataHolder)RecordMap.get("1");

but that key does not exist because you have overwrttien it - it only contains a key of "2" ...

SO :

If you move the line
>>> HashMap RecordMap = new HashMap();
to the very top of your static void main() method, it will work fine ...



Code:
public class Test {
    public static void main(String[] args) throws IOException {
			 	HashMap RecordMap = new HashMap();

                File output = new File("N:/output.txt");
                FileWriter out = new FileWriter(output);
                BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File("N:/Printer.txt"))));
        String line = "";
                int tokenid = 0;
                int id = 0;
                String date = "";
                String username = "";
                String printer = "";
                String document = "";
                String pages = "";

                PrintingRecord myrecord = new PrintingRecord(id, date, username, printer, document, pages);

                myrecord.id = 0;

                while((line= reader.readLine()) != null) { //Keep on reading in lines until EOF
            System.out.println(line);   //reading in all lines ok
                       StringTokenizer st = new StringTokenizer(line, ",;:");

                       String token;
                       tokenid = 0;
                       myrecord.id++;

                       while(st.hasMoreTokens()){ //while there are still tokens to read
            out.flush();

                        token = st.nextToken();
                        out.write(token); //output token to file
                        out.write('\n');

                          //assign variables to tokens
                        if (tokenid == 0){
                          myrecord.date= token;
                           }

                        if (tokenid == 8){
                          myrecord.username = token;
                            }

                        if (tokenid == 11){
                          myrecord.printer = token;
                            }

                        if (tokenid == 13){
                          myrecord.pages = token;
                            }

                          tokenid++;
                       }

                       System.out.println("Date  " + myrecord.date + "Token ID is  " + tokenid);
                       System.out.println("Username  " + myrecord.username + "Token ID is  " + tokenid);
                       System.out.println("Printer  " + myrecord.printer + "Token ID is  " + tokenid);
                       System.out.println("RecordID is  " + myrecord.id);



                      MyDataHolder mdh = new MyDataHolder();
                      mdh.setIntVal(myrecord.id);
                      mdh.setStrVal(myrecord.username);
                      String myrecordidasString = myrecord.id + "";
                      RecordMap.put(myrecordidasString, mdh);

                      // and to retrieve

                      MyDataHolder mdh2 = (MyDataHolder)RecordMap.get("1");
                      System.err.println(mdh2.getIntVal() +" " + mdh2.getStrVal());


                }

               out.close();
    }


   public static class PrintingRecord {
       public PrintingRecord(int id_, String date_, String username_, String printer_, String document_, String pages_){
           id = id_;
           username = username_;
           printer = printer_;
           document = document_;
           pages = pages_;

       }
                public int id =0;
                public String date;
                public String username;
                public String printer;
                public String document;
                public String pages;


   }

public static class MyDataHolder {

   private int intVal = 0;
   private String strVal = "";

    public void setIntVal(int intVal) {
        this.intVal = intVal;
    }

    public int getIntVal() {
        return intVal;
    }
    public void setStrVal(String strVal) {
        this.strVal = strVal;
    }

    public String getStrVal() {
        return strVal;
    }
}
}

PS : I really would move the inner classes out of this main method and make them non-static classes ...
 
HashMap RecordMap = new HashMap();
MyDataHolder mdh = new MyDataHolder();
mdh.setIntVal(myrecord.id);
mdh.setStrVal(myrecord.username);
String myrecordidasString = myrecord.id + "";
RecordMap.put(myrecordidasString, mdh);


Why not just put myrecord in the Hashtable?

RecordMap.put(myrecordidasString, myrecord);
 
Ok magic thanks guys. One more question how would i then get the information out of the hashMap so i can compare it to other records. I know if i do

Object Recordx = RecordMap.get("1");

It will return the myrecord values stored in recordid = 1 but how do i then get out for example the username? I tried

System.out.println("Record 1 username is:" + Recordx.username);

But it didn't like it. Any ideas?
 
You have to cast Recordx to "PrintingRecord" first.

PrintingRecord pr = (PrintingRecord)RecordMap.get(1);
... pr.username ... ;
 
Thankyou!!
It only seems to be getting values from the last entry to the hashmap. It doesn't matter which record id i ask for it only give me values for the last one read in.

I don't really want to post all my code again as this post is massive as it is. So the only bit that has changed is after where i have a series of if statements assigning names to the tokens i have...

Code:
if (tokenid == 13){
                          myrecord.pages = token;                            
                            }                    
                        
                          tokenid++;                                          
                       
                       }
                        
                       System.out.println("Date  " + myrecord.date + "Token ID is  " + tokenid);                                             
                       System.out.println("Username  " + myrecord.username + "Token ID is  " + tokenid);    
                       System.out.println("Printer  " + myrecord.printer + "Token ID is  " + tokenid);
                       System.out.println("RecordID is  " + myrecord.id);   
                                    
                     
                      String myrecordidasString = myrecord.id + "";
                      RecordMap.put(myrecordidasString, myrecord);
                                                                                                                       
                      
                }
               PrintingRecord pr = (PrintingRecord)RecordMap.get("1"); 
               System.out.println("Record 1 username is:" + pr.username);
               PrintingRecord pr12 = (PrintingRecord)RecordMap.get("16"); 
               System.out.println("Record 12 printer is:" + pr12.printer);
               out.close();                            
	}

The output for pr and pr12 are both for the last record read in which should be if i kept calling them the same pr19.

Any ideas where i've gone wrong?
 
Without looking in detail to your code I would say you are always using the same myrecord and changing it everytime. You should move the creation of the new PrintingRecord(...) to inside the while loop.
=== Your code ===
PrintingRecord myrecord = new PrintingRecord(id, date, username, printer, document, pages);
myrecord.id = 0;
while((line= reader.readLine()) != null) {

=== Should become ===
myrecord.id = 0;
while((line= reader.readLine()) != null) {
PrintingRecord myrecord = new PrintingRecord(id, date, username, printer, document, pages);
 
If i do that it sets the myrecord.id to be 1 everytime. It also gives me an error...

java.lang.NullPointerException
at Test.main(Test.java:77)
Exception in thread "main" 

I'm sorry to be a pain but i'm so close to getting it working.

 
First problem : In the while loop, you will have to keep track of a seperate counter. eg

Before while :

int count = 0;

In while :

myrecord.id = count++;

For your second problem, I do not know what is on line 77
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top