Help please!! Arraylist Search/Count

Hi everyone,

I'm very new to Java. My problem is this:

I have created a program that parses many XML files. Now I want to generate a report of the number of files that contain each unique date within the xml files.

For example:

Using the Filewriter, I will like to write the number of files out of the 100 present that contain the following dates:

2005-07-12

2005-08-11

So far my attempts are to store all the dates parsed into an arraylist. I've tried using the popular wordcount.java and many other examples to no avail. If there are any methods out there that can help me count the unique items present in the arraylist, I will really appreciate it.

If I going about it the wrong way and there's a better way, can some also be shout it out.

Many many thanks

[825 byte] By [Tellya] at [2007-11-26 13:03:24]
# 1
I don't get you. How about creating queriable objects representing your file's data, and then iterating over the list getting only those that match a date or whatever?
CeciNEstPasUnProgrammeura at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 2

Have you consdiered storing the information in a slightly different manner. If you look into the Collections classes, you will see classes that allow you to store key value pairs - HashMap is the one that springs to mind. Why not have the date as the key and a running count of the number of occurrences as the value? It is possible to query the collection to say does this key exits, if not create a new mapping, if it does exits then get the value, increment by one and store it back again.

Tillermana at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 3

If you can able to store all the dates in an array list and want to find the uniques dates in that array list, then this program is enough...

import java.util.*;

import java.awt.*;

public class forTelly{

ArrayList al;

forTelly(){

al=new ArrayList();

String s[]={

"2005-07-12","2005-08-11","2005-07-12","2005-08-11",

"2005-04-12","2005-03-11","2005-02-12","2005-01-11",

};

for(int i=0;i<s.length;i++)

al.add(s[i]);

/* so now we can consider that your source

arraylist is al from this we are going to

find the number of unique dates...okay.....

*/

ArrayList aldest=new ArrayList();

/* we can create another array list in

which we will add all the unique date

*/

for(int i=0;i<al.size();i++){

if(aldest.size() >< 1) aldest.add(al.get(i));

else{

if(!aldest.contains(al.get(i)))

aldest.add(al.get(i));

}

}

System.out.println("So the number of unique address in the source Arr..Li...is:"+aldest.size());

}

public static void main(String args[]){

new forTelly();

}

}

Is this what you want?

Note: That < symbol may change to <> or >< so please correct it...

pravintha at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 4
'grep' works great too.
robtafta at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 5

Thanks for the reply.

Infact its not only the dates that are an issue. I actually have many other objects that I will need to 'count' as it were. However, I used the dates as an example.

All of the elements a queriable objects. I'm able to read the data 'per instance (i.e. per metadata file parsed).

The dates therefore are objects but because they are compiled from the 100 individuals files I need to store them into place so as to sort them and count them eventually.

Any better?

Thanks

Tellya at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 6

> Have you consdiered storing the information in a

> slightly different manner. If you look into the

> Collections classes, you will see classes that allow

> you to store key value pairs - HashMap is the one

> that springs to mind. Why not have the date as the

> key and a running count of the number of occurrences

> as the value? It is possible to query the collection

> to say does this key exits, if not create a new

> mapping, if it does exits then get the value,

> increment by one and store it back again.

Tillerman,

I think you are close understanding my problem. Do you have a solution to how I could keep the dates as a key and the occurrences as a count?

I will appreciate any mockup code.

Many thanks

Tellya at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 7

> If you can able to store all the dates in an array

> list and want to find the uniques dates in that array

> list, then this program is enough...

> > import java.util.*;

> import java.awt.*;

>

> public class forTelly{

>ArrayList al;

> forTelly(){

> al=new ArrayList();

> String s[]={

>

> 2005-07-12","2005-08-11","2005-07-12","2005-08-11",

>

> 2005-04-12","2005-03-11","2005-02-12","2005-01-11",

> };

> for(int i=0;i<s.length;i++)

>al.add(s[i]);

>/* so now we can consider that your source

>arraylist is al from this we are going to

>find the number of unique dates...okay.....

> */

> rrayList aldest=new ArrayList();

> /* we can create another array list in

> which we will add all the unique date

>*/

> for(int i=0;i<al.size();i++){

> if(aldest.size() < 1)

> aldest.add(al.get(i));

>else{

>if(!aldest.contains(al.get(i)))

>aldest.add(al.get(i));

> }

> System.out.println("So the number of unique address

> in the source Arr..Li...is:"+aldest.size());

>

>}

> public static void main(String args[]){

> new forTelly();

>

> }

>

> Is this what you want?

> Note: That < symbol may change to <> or >< so please

> correct it...

pravinth,

Thanks for the code. I've already tried this snippet and it doesn't quite do what I need it to do as I have to cast the arraylist of objects to an string array and then even when I do it still prints all the dates with the number of occurences instead of a simply summary of say:

2005-07-12: 2 files

2005-08-11: 2 files

2005-01-11: 1 files

etc. etc.

Will appreciate any further thought on this.

Thanks,

Tellya at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 8

But Telly i think this is a simple solution only.

You can type cast into string then try like this:

import java.util.*;

import java.awt.*;

public class forTelly{

ArrayList al,aldest;

forTelly(){

al=new ArrayList();

aldest=new ArrayList();

Object s[]={

"2005-07-12","2005-08-11","2005-07-12","2005-08-11",

"2005-04-12","2005-03-11","2005-02-12","2005-01-11",

};

for(int i=0;i<s.length;i++)

al.add(s[i]);

for(int i=0;i<al.size();i++){/*below >< may change into >< plz correct it... */

if(aldest.size()<1) aldest.add(al.get(i));

else{

if(!aldest.contains(al.get(i)))

aldest.add(al.get(i));

}

}

int no[]=new int[aldest.size()];

for(int j=0;j<aldest.size();j++){

for(int i=0;i<al.size();i++){

if(al.get(i).equals(aldest.get(j))) no[j]++;

}

}

for(int i=0;i<aldest.size();i++)

System.out.println(aldest.get(i)+":"+no[i]+"files");

}

public static void main(String args[]){

new forTelly();

}

}

>

pravintha at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 9

Sorry for the dealy; just battled home through traffic!!

Here is a bit of code for you;

import java.util.Hashtable;

import java.util.Enumeration;

public class DateCount {

private Hashtable<String, Occurrence> dates = null;

public DateCount() {

// Note the typing of the Hashtable to save explicit casts later

this.dates = new Hashtable<String, Occurrence>();

}

public void countDates(String[] dateArray) {

String strDate = null;

Occurrence occ = null;

// Get each element from the array of dates

for(String date : dateArray) {

// Check if the Hashtable already contains an entry for this

// String (date)

if(dates.containsKey(date)) {

// If it does, recover the matching Occurrence object

occ = dates.get(date);

// And increment the count by one

occ.increment();

}

else {

// If a match was not found for the date, create an new

// instance of the Occurrence class and store it into

// the Hashtable using the String (date) as the key

dates.put(date, new Occurrence());

}

}

}

public String getResults() {

// Using StringBuffer to assemble the results string

StringBuffer buffer = new StringBuffer();

// Will hold each kesy value recovered from Enumeration

String key = null;

// Will hold the Occurrence object

Occurrence occ= null;

// Get an Enumeration over the Hashtables keys

Enumeration<String> keys = dates.keys();

// While there are still keys to be processed

while(keys.hasMoreElements()) {

// Get a key

key = keys.nextElement();

// Recover the matching Occurrence object

occ = dates.get(key);

// Append the info to the StringBUffer. The key (date) first

buffer.append(key);

// Next a comma to separate

buffer.append(", ");

// Then the number of occurrences

buffer.append(occ.getOccurrences());

// Finally, end this line with a carriage return

buffer.append(System.getProperty("line.separator"));

}

// Convert StringBuffers contents into a String, trim and return

return(buffer.toString().trim());

}

public static void main(String[] args) {

// Create an instance of the DateCount class

DateCount dc = new DateCount();

// Pass the cointDates() method an array of Strings containing dates.

dc.countDates(new String[]{"10/10/2006",

"01/05/2004",

"30/01/2003",

"10/10/2005",

"02/05/2004",

"10/10/2006",

"10/10/2006",

"01/01/1994",

"02/07/1987",

"02/09/2004",

"01/01/1995",

"10/10/2006",

"01/01/1994",

"02/09/2003",

"02/09/2004",

"02/09/2003"});

// Print out the results

System.out.println(dc.getResults());

}

}

// All this class does is wrap a primitive int value and provide methods to

// increment it and get the total.

public class Occurrence {

private int count = 0;

// Constructor to establish intial value; 1 in this case

public Occurrence() {

count = 1;

}

// Add one to the count

public void increment() {

this.count++;

}

// Return the total number of occurrences, the count

public int getOccurrences() {

return(count);

}

}

As you can see, there are two classes; DateCount and Occurrence (not very well named I know but well.....)

Occurrence simply warps a primitive int and provides methods that allow you to increment the count and get the total count. There will be one Occurrence obhject for each unique date. If there are matching dates then we simply increment the relevant Occurrence object's count.

All of the action takes place in the DateCount class. Take a look at the countDates() method in detail. It is passed an array of String(s) where each element is a 'date', I used this just for testing and I am sure that once you get the idea, you can modify it so that the technique works for you. Anyway, all I do is get an element from the array, check to see if an entry already exists in the Hashtable for this 'date'. If I find one, then I get the associated Occurrence object and increment the count, if there is no match, I create a new entry in the Hashtable where the 'date' is the key and a new Occurrence object the value.

Remember that the Hashtable will store key/value pairs. I have chosen to make the 'date' into the key and an instance of the Occurrence class into the value.

At the end, all I do is call the getResults() metjod of the DateCount class to, well, get the results. It is the main() method of the DateCoutn class that drives this whole example, so compile both classes and run that one.

Hope that is clear, if not just drop me an e-mail.

Tillermana at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 10

> Sorry for the dealy; just battled home through

> traffic!!

>

> Here is a bit of code for you;

>

> import java.util.Hashtable;

> import java.util.Enumeration;

>

> public class DateCount {

>

> private Hashtable<String, Occurrence> dates = null;

>

> public DateCount() {

> // Note the typing of the Hashtable to save

> ve explicit casts later

> this.dates = new Hashtable<String, Occurrence>();

> }

>

> public void countDates(String[] dateArray) {

> String strDate = null;

> Occurrence occ = null;

> // Get each element from the array of dates

> for(String date : dateArray) {

> // Check if the Hashtable already contains an

> an entry for this

> // String (date)

> if(dates.containsKey(date)) {

> // If it does, recover the matching Occurrence

> ence object

> occ = dates.get(date);

> // And increment the count by one

> occ.increment();

> }

> else {

> // If a match was not found for the date, create

> eate an new

> // instance of the Occurrence class and store it

> e it into

> // the Hashtable using the String (date) as the

> the key

> dates.put(date, new Occurrence());

> }

> }

>

> }

>

> public String getResults() {

> // Using StringBuffer to assemble the results

> ts string

> StringBuffer buffer = new StringBuffer();

> // Will hold each kesy value recovered from

> om Enumeration

> String key = null;

> // Will hold the Occurrence object

> Occurrence occ= null;

> // Get an Enumeration over the Hashtables keys

> Enumeration<String> keys = dates.keys();

> // While there are still keys to be processed

> while(keys.hasMoreElements()) {

> // Get a key

> key = keys.nextElement();

> // Recover the matching Occurrence object

> occ = dates.get(key);

> // Append the info to the StringBUffer. The key

> key (date) first

> buffer.append(key);

> // Next a comma to separate

> buffer.append(", ");

> // Then the number of occurrences

> buffer.append(occ.getOccurrences());

> // Finally, end this line with a carriage return

> buffer.append(System.getProperty("line.separator"))

> ;

> }

> // Convert StringBuffers contents into a String,

> g, trim and return

> return(buffer.toString().trim());

> }

>

> public static void main(String[] args) {

> // Create an instance of the DateCount class

> DateCount dc = new DateCount();

> // Pass the cointDates() method an array of Strings

> gs containing dates.

> dc.countDates(new String[]{"10/10/2006",

>"01/05/2004",

>"30/01/2003",

>"10/10/2005",

>"02/05/2004",

>"10/10/2006",

>"10/10/2006",

>"01/01/1994",

>"02/07/1987",

>"02/09/2004",

>"01/01/1995",

>"10/10/2006",

>"01/01/1994",

>"02/09/2003",

>"02/09/2004",

>"02/09/2003"});

> // Print out the results

> System.out.println(dc.getResults());

> }

>

> }

>

> // All this class does is wrap a primitive int value

> and provide methods to

> // increment it and get the total.

> public class Occurrence {

>

> private int count = 0;

>

> // Constructor to establish intial value; 1 in this

> s case

> public Occurrence() {

> count = 1;

> }

>

> // Add one to the count

> public void increment() {

> this.count++;

> }

>

> // Return the total number of occurrences, the

> e count

> public int getOccurrences() {

> return(count);

> }

>

> }

>

> As you can see, there are two classes; DateCount and

> Occurrence (not very well named I know but

> well.....)

>

> Occurrence simply warps a primitive int and provides

> methods that allow you to increment the count and get

> the total count. There will be one Occurrence obhject

> for each unique date. If there are matching dates

> then we simply increment the relevant Occurrence

> object's count.

>

> All of the action takes place in the DateCount class.

> Take a look at the countDates() method in detail. It

> is passed an array of String(s) where each element is

> a 'date', I used this just for testing and I am sure

> that once you get the idea, you can modify it so that

> the technique works for you. Anyway, all I do is get

> an element from the array, check to see if an entry

> already exists in the Hashtable for this 'date'. If I

> find one, then I get the associated Occurrence object

> and increment the count, if there is no match, I

> create a new entry in the Hashtable where the 'date'

> is the key and a new Occurrence object the value.

>

> Remember that the Hashtable will store key/value

> pairs. I have chosen to make the 'date' into the key

> and an instance of the Occurrence class into the

> value.

>

> At the end, all I do is call the getResults() metjod

> of the DateCount class to, well, get the results. It

> is the main() method of the DateCoutn class that

> drives this whole example, so compile both classes

> and run that one.

>

> Hope that is clear, if not just drop me an e-mail.

Many thanks Tillerman,

I'm still playing around with the code. I'm in the UK so I guess there will be a time-lag (if you are in the States that is).

Will get in touch via email if I'm still stuck.

Thanks,

Telly

Tellya at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 11
You can use a bag: http://forum.java.sun.com/thread.jspa?threadID=5117518&tstart=50
govisagod512a at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 12

Hi Pravinth,

You are right the solution is very simple. Your code works superbly. I stripped the main code from the class and embedded it into my main class and then cast my arraylist to a string array and bingo! So I'm going to award you Duke dollars.

Many many thanks,

Telly

Tellya at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 13
> So I'm> going to award you Duke dollars.> Hallelujah! An honest poster.
Minkoa at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 14

> > So I'm

> > going to award you Duke dollars.

> >

>

> Hallelujah! An honest poster.

Hallelujah, Amen!

In life I've learnt that honesty PAYS!! Whatever you do, you do for yourself. There's nothing more valuable than one's integrity.

Anyway, I've awarded 8 Dukes to Pravinth because he's solution was simply and straightforward whilst giving 2 Dukes to Tillerman simply because his code also works but gosh, I don't have a clue as to instantiating multiple clasess...Remember, I'M NEW TO JAVA!

Thanks for all ya help.

Telly.

Tellya at 2007-7-7 17:07:54 > top of Java-index,Java Essentials,New To Java...
# 15

Thanks for the reply Telly.

When you get the time give it another look over. The reason for having that wrapper class - Occurrence - was that it would be possible for you create other subclasses of this one to deal with counting other types of object; perhaps storing the original object inside the class along with the counter. Any questions just e-mail.

Tillermana at 2007-7-21 15:44:58 > top of Java-index,Java Essentials,New To Java...