简体   繁体   中英

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM