Having just worked on it this afternoon, I've realised that the ideal class
exists - MultiHashMap.
MultiHashMap holds a list of elements for each key, exactly as you describe:
MultiMap multi = new MultiHashMap();
Man[] men = ...
for (int i =0; i < men.length; i++) {
multi.put(men[i].age, men[i]);
}
After looping through all the men, the MultiMap will contain a key for each
age. Each key will hold a list of the Man objects. Thus using the data from
the email below:
multi.get(new Integer(35) ==> {('Isac', 35) , ('Gonsales', 35)},
multi.get(new Integer(32) ==> {('Jerry', 32) , ('Hans', 32) , ('Mussa',
32)},
multi.get(new Integer(22) ==> {('Moshe' , 22)}
This seems to solve the problem.
Stephen
----- Original Message -----
From: "Rob Oxspring" <[EMAIL PROTECTED]>
> How about adding a method to CollectionUtils along the lines of the
following:
>
> public static Collection group(Collection source, Transformer grouper){
> Map groups = new HashMap();
> Iterator i = source.iterator();
> while(i.hasNext()){
> Object value = i.next();
> Object key = grouper.transform(value);
> Collection group = (Collection)groups.get(key);
> if(group==null){
> group = new ArrayList();
> groups.put(key,group);
> }
> group.add(value);
> }
> return groups.values();
> }
>
> and then using a transformer along the lines of:
>
> class AgeGrouper implements Transformer{
> public Object transform(Object input){
> Man man = (Man)input;
> return String.valueOf(man.age);
> }
> }
>
> then CollectionUtils.group(source, ageGrouper) should produce something
like:
> {
> {('Isac', 35) , ('Gonsales', 35)},
> {('Jerry', 32) , ('Hans', 32) , ('Mussa', 32)},
> {('Moshe' , 22)}
> }
>
> This seems to solve the required problem in a single pass, although the
number of map lookups might offset this? It's a pattern I
> find myself repeating lots, except that I normally return the map rather
than just values and I allow an optional Map parameter so
> that a TreeMap can be used on occasions (also allows using a non ArrayList
for each group iff you know the group keys in advance).
>
> Should I send a patch?
>
> Rob
>
> ----- Original Message -----
> From: "Chintan" <[EMAIL PROTECTED]>
> To: "Jakarta Commons Developers List" <[EMAIL PROTECTED]>
> Sent: Sunday, November 10, 2002 10:03 PM
> Subject: Re: [Collection] Is there a way to branch (group) a collection?
>
>
> > I am not aware of any direct functionality but Collection.retainAll()
can be used to the grouping.
> >
> > public interface Predicate {
> > public boolean evaluate(Object obj);
> > }
> >
> > class Man {
> > private int age;
> > private String name;
> > private Predicate predicate; //Strategy.
> >
> > public Man(int a, String n){
> > this.age = a;
> > this.name = n;
> > }
> >
> > //override equals
> > public boolean equals(Object obj) {
> > if(predicate != null)
> > return predicate.evaluate(obj);
> > else
> > //Override equals here.
> > //Do normal comparison
> > }
> > public static Collection grouped(Collection sourceCollection,
> > Predicate p, Man type) {
> > predicate = p;
> > return sourceCollection.retainAll(new ArrayList().add(type));
> > }
> > }
> >
> > public class FindPredicate{
> > public static void main(String[] args){
> > ArrayList men = new ArrayList();
> > for(int i = 0 ;i < 30; i++)
> > men.add(new Man("Name: " + 1, i);
> > //From the above collection get all men with age 25
> > System.out.println(Man.grouped(men, new Predicate() {
> > public boolean evaluate(Object obj) {
> > //Compare ages.
> > if(age == (Man)obj.age) return true;
> > return false;
> > }
> > }, new Man("", 25));
> > }
> > }
> >
> >
> >
> > Roman Rytov wrote:
> >
> > >Assume a collection of objects exists and there is an object
> > >implementing Predicate interface. Also let's say that evaluate(Object
> > >obj) method returns a number of distinct objects (out of this
> > >collection) and the number is noticeably less than total amount of
> > >objects in the collection. Is there a way to get all collections
grouped
> > >by the predicator? An example may be schematically written like:
> > >
> > >class Man {
> > >String name;
> > >int age;
> > >}
> > >
> > >class AgePredicator implements Predicate {
> > > int age;
> > > boolean evaluate (Object obj) {
> > >Man man = (Man)obj;
> > >return man.age == this.age;
> > >}
> > >
> > >
> > >collection men = { ('Isac', 35), ('Jerry', 32), ('Gonsales', 35),
> > >('Moshe' , 22), ('Hans', 32), ('Mussa', 32)}
> > >
> > >afer grouping it's supposed to get 3 collections:
> > >
> > >('Isac', 35), ('Gonsales', 35),
> > >('Jerry', 32), ('Hans', 32), ('Mussa', 32)}
> > >('Moshe' , 22),
> > >
> > >
> > >Do we have something in the API do achieve it easily?
> > >
> > >
> > >_______________________
> > >Roman Rytov
> > >
> > >
> > >
> > >
> >
> >
> > --
> > To unsubscribe, e-mail:
<mailto:[EMAIL PROTECTED]>
> > For additional commands, e-mail:
<mailto:[EMAIL PROTECTED]>
> >
> >
> >
>
>
> --
> To unsubscribe, e-mail:
<mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail:
<mailto:[EMAIL PROTECTED]>
>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>