views:

51

answers:

2

Best explained with code I think, this is just a simple example:

public class MyPOJO {

    public String name;
    public int age;

    public MyPOJO(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class MyProcessor {

    public List<MyPOJO> process(List<MyPOJO> mypojos) {
        List<MyPOJO> temp = new ArrayList<MyPOJO>; 
        for (int i=0; i <moypojos.size(); i++) {
            if (filterOne(mypojos[i])) continue;
            if (filterTwo(mypojos[i])) continue;
            if (filterThree(mypojos[i])) continue;
            temp.add(mypojos[i];
        }
    }

    public boolean filterOne(MyPOJO mypojo) {
        // in practice filters aren't so basic
        return (mypojo.age < 21);
    }
    // assume implementations for the other filter methods
}

Yikes that's ugly. Basically I have a collection and I'd like to pass it through a sieve of sorts to only continue processing the objects that meet a certain criteria. My guess is there is a better pattern for this than a bunch of methods that return booleans.

+2  A: 

You can have list of IFilters.

like so

boolean filtersResult = false;
for (IFilter filter : filters) {
    filterResult = filter.process(mypojos[i])

    if (filterResult)
        break;
}
Mykola Golubyev
Turning the filters into objects allows you to pass them around easily. So you could pass the list to the processor along with instances of each of the filters you want applied. This is probably the best way to handle this.
Daniel Bingham
Ok, I know I'm changing the problem a bit, but suppose one of the filters needs to filter out the mypojo if its age is in a Set of bad ages? So we have a Set<int> that it needs to compare with. Do i modify the interface method to also take a Set parameter and not use it for the other filters?
DanInDC
it will be filter which receives set of ages in constructor and implements process method using that passed set.
Mykola Golubyev
A: 

You may want to implement your filters such that they take a collection, and return a filtered collection:

public interface IFilter<E> {
  public Collection<E> filter(Collection<E> input);
}

This way you can chain together filters very trivially. The downside is that for large collections it is slower and takes more space; but the code is a lot more readable.

Alex Feinman