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>