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]>

Reply via email to