I'm learning about generics and I don't know how to resolve a problem.
This is the code:
public abstract class AbstractMapService<T, ID> {
protected Map<ID, T> map = new HashMap<>();
Set<T> findAll(){
return new HashSet<>(map.values());
}
T findById(ID id) {
return map.get(id);
}
T save(ID id, T object){
map.put(id, object);
return object;
}
void deleteById(ID id){
map.remove(id);
}
void delete(T object){
map.entrySet().removeIf(entry -> entry.getValue().equals(object));
}
private Long getNextId() {
return Collections.max(map.keySet()) + 1;
}
}
And this is the error:
max(java.util.Collection<? extends T>) in Collections cannot be applied to (java.util.Set<ID>)
reason: no instance of type variable(s) T exist so that ID conforms to Comparable<? super T>
Can someone explain to me why I get this error and how to resolve it? Thank you!
This error means the elements in the parameter Collection
of method Collections.max
should implement interface Comparable
. So it can use the compareTo
to find the max elements in the Collection
.
You can make it compile by declaring it this way:
public abstract class AbstractMapService<T, ID extends Comparable<ID>>
private ID getNextId() {
return Collections.max(map.keySet());
}
but I do not think this make much sense.
You might want to re-consider your design. With your current code, the ID
can be any type. For exmaple, it could be String
. And this time, your getNextId
should not return current maxID + 1
, since the +1
is only make sense when your ID
is a Number
.
If ID
is supposed to be Long
, then you should not declare it as type parameter, you can write it this way:
public abstract class AbstractMapService<T> {
protected Map<Long, T> map = new HashMap<>();
Set<T> findAll(){
return new HashSet<>(map.values());
}
T findById(Long aLong) {
return map.get(aLong);
}
T save(Long aLong, T object){
map.put(aLong, object);
return object;
}
void deleteById(Long aLong){
map.remove(aLong);
}
void delete(T object){
map.entrySet().removeIf(entry -> entry.getValue().equals(object));
}
private Long getNextId() {
return Collections.max(map.keySet()) + 1L;
}
}