Non so se può esserti utile (e se è quanto ti aspetti) ma vedi questo. Data una interfaccia generica:

codice:
public interface ObjectFilter<T> {
    boolean accept(T t);
}

codice:
import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<Object> oggetti = new ArrayList<Object>();
        List<Integer> interi = new ArrayList<Integer>();

        interi.add(14);
        interi.add(34);
        interi.add(25);
        interi.add(9);

        ObjectFilter<Number> numFilter = new ObjectFilter<Number>() {
            public boolean accept(Number num) {
                return num.doubleValue() < 20;
            }
        };

        filtra(interi, oggetti, numFilter);

        System.out.println(oggetti);
    }

    public static <T> void filtra(List<? extends T> src, List<? super T> dst, ObjectFilter<? super T> filter) {
        for (T t : src) {
            if (filter.accept(t)) {
                dst.add(t);
            }
        }
    }
}

Ti è chiaro perché ho usato i bound in quel modo in filtra?