No instance of type variable(s) T exist so that ID conforms to Comparable<? super T>

elvis :

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!

xingbin :

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;
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=95359&siteId=1