Toto
Toto

Reputation: 19

Java: compilation error with generic function reference

Could someone help me to fix this compilation error, please?

I 'd like to define a map method in the generic interface called Suite and use it like this:

Suite < Integer > suite2 = Suite.from("34", "78", "23").map(Integer::parseInt);

assertEquals(3, suite.size());
assertEquals(34, (int)suite.get(0));
assertEquals(78, (int)suite.get(1));
assertEquals(23, (int)suite.get(2));

The the call to the same method with a function and parameter compile well:

Suite<Integer> suite1 = Suite.from(1, 2).map(x -> x * 2);

assertEquals(2, suite.size());
assertEquals(2, (int)suite.get(0));
assertEquals(4, (int)suite.get(1));

So I've defined the method in the interface like this

public interface Suite<E> {

    public <E> Suite<E> map(int i, Function<? super E, ? extends E> f);
}

Note: this is almost the same protytype as the map method of Stream class (except the paramter i )

My problem is in my test, this line does not compile:

map(Integer::parseInt)

because of these errors:

  • The type Integer does not define toString(Object) that is applicable here.
  • Type mismatch: cannot convert Suite<Object> to Suite<String>

I'm tried to redefine the function with a Supplier<E> but it does not work.

Upvotes: 0

Views: 413

Answers (2)

radistao
radistao

Reputation: 15534

Usually functional mapping expects type changing, e.g. argument and result types are diverged:

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#map-java.util.function.Function-

Suite < Integer > suite2 = Suite.from("34", "78", "23").map(Integer::parseInt);

Here you change String type to Integer, thus you can't use common E generic name like

public <E> Suite<E> map(int i, Function<? super E, ? extends E> f);

but:

public <T, R> Suite<R> map(int i, Function<? super T, ? extends R> f);

or:

public interface Suite<E> {
    public <R> Suite<R> map(int i, Function<? super E, ? extends R> f);
}

Upvotes: 2

Jose Martinez
Jose Martinez

Reputation: 12022

 Function<? super E, ? extends E> function

Integer is not a super class of String, hence this fails:

Suite <String> suite1 = Suite.span(1, Integer::toString);

reference: Difference between <? super T> and <? extends T> in Java

Upvotes: 2

Related Questions