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:commons-dev-unsubscribe@;jakarta.apache.org>
> For additional commands, e-mail: <mailto:commons-dev-help@;jakarta.apache.org>
>
>
>


--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@;jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@;jakarta.apache.org>

Reply via email to