That's basically my first touch with Java generic types and I can't figure out what is wrong with the following piece of code.
I have a helper class Helper
with a static function inRange
usng generic type that should return the list of objects from an input list that are in certain range
around object at index index
(I haven't tested it yet, it's not an issue here if it works correctly or not):
public class Helper {
public static <T> List<T> inRange(List<T> list, int index, int range) {
List<T> res = new ArrayList<T>();
int N = list.size();
assert(index < N);
if (N == 0)
return res;
int i, j;
/* right range */
i = (index + 1) % N;
j = 0;
while (i != index && j < range) {
res.add(list.get(i));
i = (i + 1) % N;
j++;
}
/* left range */
i = (N + index - 1) % N;
j = 0;
while (i != index && j < range && !res.contains(list.get(i))) {
res.add(lista.get(i));
i = (N + i - 1) % N;
j++;
}
return res;
}
}
Then I want to use it in a class:
import java.util.ArrayList;
public class StrategyA extends StrategyB {
public Decision makeDecision(GameView gameView, Action action, View playerView) {
int pos = gameView.activePlayersViews().indexOf(playerView);
assert(pos != -1);
ArrayList<View> inRange = Helper.inRange(gameView.activePlayersViews(), pos,
playerView.range());
// todo ...
return new Decision(Decision.KindOfDecision.DO_NOTHING, 0);
}
}
where gameView.activePlayersView()
is of type ArrayList<View>
.
Then from my IDE (IntelliJ IDEA) on the line calling inRange(..)
I get
Error:(8, 56) java: incompatible types: no instance(s) of type variable(s) T exist so that java.util.List<T> conforms to java.util.ArrayList<View>
Even I change generic type T
directly to View
I still get this error
ArrayList
is an implementation of List
interface.
So all ArrayList
instances are List
instances but all List
instances are not necessarily ArrayList
.
So when you call this method :
public static <T> List<T> inRange(List<T> list, int index, int range) {
you cannot assign its result to an ArrayList
as you are doing :
ArrayList<View> inRange = Helper.inRange(...);
Go on to program by interface and use List
in both sides :
List<View> inRange = Helper.inRange(...);
Minimize your example like (using Integer of the templated List type):
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
List<Integer> list = new ArrayList<Integer>();
ArrayList<Integer> inRange = Helper.inRange(list, 0,1);
}
}
class Helper {
public static <T> List<T> inRange(List<T> list, int index, int range) {
List<T> res = new ArrayList<T>();
return res;
}
}
Then even if you put template types out of the picture:
ArrayList inRange = Helper.inRange(list, 0,1);
public static List inRange(List list, int index, int range) { ... }
you see that while the helper static method returns a List, you are trying to assign it to an ArrayList, and that's your problem, as ArrayList is a concrete implementation of List, but you cannot assign a reference to a generic List to a concrete implementation of ArrayList
Just change to:
List<View> inRange = Helper.inRange(gameView.activePlayersViews(), pos,
playerView.range());
and you are good to go: https://ideone.com/MXZxqz
It happens, because inRange()
returns type List<T>
. You can store result in reference with type List
or any supertype.
Try to use this code:
List<View> inRange = Helper.inRange(gameView.activePlayersView(), pos,
playerView.range());
Try to do:
List<View> inRange = Helper.inRange(gameView.activePlayersView(), pos,
playerView.range());
And check this:
res.add(lista.get(i));
there is no lista in this class
You need to cast the type ArrayList
to be List
ArrayList<View> inRange = Helper.inRange((List<View>) gameView.activePlayersViews(), pos,
playerView.range());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With