Can someone help me with understanding logic behind this code:
import java.util.List;
import java.util.Arrays;
interface DoubleValue<T> {
public void dv(T e);
}
public class InTest2 {
public static void main(String[] a) {
DoubleValue<Number> func = e -> System.out.println(e.doubleValue());
List<Number> l = Arrays.asList(1, 2, 3);
InTest2.sumOfListNotWorking(l, func);
InTest2.sumOfListWorking(l, func);
InTest2.sumOfListWorkingSuper(l, func);
}
// I thought this should work
public static void sumOfListNotWorking(List<? extends Number> list, DoubleValue<? extends Number> f) {
for (Number n : list)
f.dv(n); // This line give error: The method dv(capture#2-of ? extends Number) in the type DoubleValue<capture#2-of ? extends Number> is not applicable for the arguments (Number)
}
public static void sumOfListWorking(List<? extends Number> list, DoubleValue<Number> f) {
for (Number n : list)
f.dv(n);
}
public static void sumOfListWorkingSuper(List<? extends Number> list, DoubleValue<? super Number> f) {
for (Number n : list)
f.dv(n);
}
}
sumOfListNotWorking:
Here I pass to DoubleValue.dv(<? extends Number> e) a Number and I thought it's OK.
But compiler says that it's not. Why?
I expect with DoubleValue<Number>.dv as e -> e.doubleValue() this should be typical consumer: I get value <? extends Number> and do something with it.
sumOfListWorkingSuper:
Behavior of sumOfListWorkingSuper puzzles me too.
Interface DoubleValue<? super Number> can't be a consumer cause value of <? super Number> can't be changed in place (Number is immutable), but compiler is OK with it.
UPDATE:
Apparently I didn't understand correctly logic of "producer" and "consumer".
sumOfListNotWorking:
This method doesn't compile because I use:
List<? extends Number> listas a producer (in method I take out values from list with loop).DoubleValue<? extends Number>as a consumer (in method I passNumbertof.dv(n)), but when I try to pass valueNumbertofcompiler told me thatfis defined as a producer (<? extends Number>- have some values ofNumberor it's children) and it can not accept any values. What if I passed tofargumentDoubleValue<Integer>then I would try to putNumberwhere should beInteger- this isn't possible. All this error happens because I define a producer instead of a consumer.
Thanks for pointing out word accept in logic of a consumer and a producer.