You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Roman Rytov <rr...@entopia.com> on 2002/11/10 19:41:19 UTC
[Collection] Is there a way to branch (group) a collection?
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
Re: [Collection] Is there a way to branch (group) a collection?
Posted by Stephen Colebourne <sc...@btopenworld.com>.
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" <ro...@apache.org>
> 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" <ch...@mindview.net>
> To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
> 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:
<ma...@jakarta.apache.org>
> > For additional commands, e-mail:
<ma...@jakarta.apache.org>
> >
> >
> >
>
>
> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>
>
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: [Collection] Is there a way to branch (group) a collection?
Posted by Rob Oxspring <ro...@apache.org>.
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" <ch...@mindview.net>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
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: <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>
>
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: [Collection] Is there a way to branch (group) a collection?
Posted by Chintan <ch...@mindview.net>.
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: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>