I want to write a function that will add a constant to each list element. The list can be Doubles or Integers or something similar. I write:
static <T> List<T> forEachIndexChange(List<T> list,
Function<Integer, T> cb) {
for (int i = 0; i < list.size(); ++i) {
list.set(i, cb.apply(i));
}
return list;
}
static <T extends Number> List divide(List<T> list, int val) {
return forEachIndexChange(list, i -> list.get(i) / val);
}
And then the compiler spills out that I can't call /
on class Number
:
error: bad operand types for binary operator '/'
return forEachIndexChange(list, i -> list.get(i) / val);
^
first type: T
second type: int
where T is a type-variable:
T extends Number declared in method <T>divide(List<T>,int,T)
Great, then let me overload depending on type:
static <T extends Number> List divide(List<T> list, int val, T type) {
if (type instanceof Double) {
return forEachIndexChange(list, i -> list.get(i).doubleValue() / val);
}
return null;
}
static <T extends Number> List divide(List<T> list, int val) {
if (list.size() == 0) return list;
return divide(list, val, list.get(0));
}
But this spills out an error message that I do not understand:
error: incompatible types: inference variable T#1 has incompatible bounds
return forEachIndexChange(list, i -> list.get(i).doubleValue() / val);
^
equality constraints: T#2
lower bounds: Double
where T#1,T#2 are type-variables:
T#1 extends Object declared in method <T#1>forEachIndexChange(List<T#1>,Function<Integer,T#1>)
T#2 extends Number declared in method <T#2>divide(List<T#2>,int,T#2)
Overloading on multiple T
separately also doesn't work, because, as I understand, List
erases the information about T
when overloading a function. It looks like I am basically forced to write a separate function name for each type.
How do I write a generic algorithm to permute each list element in Java? Is there a better way to approach such problems in Java?