Search code examples
javajava-streamguavaoption-type

Getting compile time error Inference variable T has incompatible bounds


class CollectorUtils {
    private CollectorUtils() {
    }

    public static <T> Collector<T, ?, T> onlyElement() {
        return Collectors.collectingAndThen(Collectors.toList(), Iterables::getOnlyElement);
    }

    public static <T> Collector<T, ?, Optional<T>> optionalElement() {
        return Collectors.collectingAndThen(Collectors.toList(), (list) -> {
            return Optional.ofNullable(Iterables.getOnlyElement(list, (Object)null));
        });
    }

    public static <T> Collector<T, ?, List<T>> toList() {
        return Collectors.toCollection(ArrayList::new);
    }
}

I am getting inference variable T has incompatible bounds.

java: incompatible types: inference variable T has incompatible bounds equality constraints: T lower bounds: T,java.lang.Object,T


Solution

  • NOTE: In this answer I'm only considering the compilation error. I'm not discussing whether the code of the question is the best possible one or not.


    I assume Iterables.getOnlyElement is from Guava.

    The problem is with this line:

    return Optional.ofNullable(Iterables.getOnlyElement(list, (Object) null));
    

    Instead, cast null to T, so that the compiler can safely infer all types:

    return Optional.ofNullable(Iterables.getOnlyElement(list, (T) null));
    

    Also, you can simplify your code:

    return Collectors.collectingAndThen(Collectors.toList(),
        list -> Optional.ofNullable(Iterables.getOnlyElement(list, (T) null)));