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