public interface Filter<M> {
boolean match(M m);
public static <T> Collection<T> filter(Collection<T> collection, Filter<T> filter) {
return collection.stream().filter(filter::match).collect(Collectors.toList());
}
////////////////////////////////////////////////////////////////
public static void main(String[] args) {
ArrayList<Integer> intList = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8));
System.out.println(intList);
List<Integer> list = filter(intList, null);
System.out.println(list);
}
}

I'm learning about java 8 streaming feature, and this is my problematic code...
I don't know why argument intList does not match filter() method. Java should know <T> is Integer here, right?

I'm not yet sure why you're getting that particular error, but the problem is that your method declares that it will return Collection<T>, but you're trying to assign the result to a List<T>. If you change the declaration of filter to:
public static <T> List<T> filter(Collection<T> collection, Filter<T> filter)
... then it compiles with no problems.
See more on this question at Stackoverflow