Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Lambda with Function<String, Object> as argument

Interesting compilation error in Lambda Java 8 (Oracle JDK)

java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

I have a method call:

new CSVFile()
.of(new FileInputStream("MyFile.csv"))
.withColumnMapping("name", "fullName", s -> s.toUpperCase())
.withColumnMapping("gender", "gender", s -> s.toUpperCase());

This is the method I'm trying to call:

 public CSVFile withColumnMapping(final String columnName, final String   beanPropertyName, final Function<String, Object> columnTransformFunction) {
    columnMappings.add(new ColumnMapping(columnName, beanPropertyName, Optional.of(columnTransformFunction)));
    return this;
}

Compilation Error I get is:

[ERROR] /Users/sai/fun/reactivecsv/src/test/java/reactivecsv/CSVFileTest.java:[26,50] cannot find symbol
[ERROR] symbol:   method toUpperCase()
[ERROR] location: variable s of type java.lang.Object

Weirdly, This compiles

Function<String, Object> upperCaseConversion = String::toUpperCase;
new CSVFile()
.of(new FileInputStream("MyFile.csv"))
.withColumnMapping("name", "fullName", upperCaseConversion)
.withColumnMapping("gender", "gender", upperCaseConversion);

Why is the compiler not able to synthesise the lambda into a Function ?

like image 267
user1189332 Avatar asked Jul 29 '15 10:07

user1189332


Video Answer


1 Answers

When you create new CSVFile() for generic type, it becomes a raw type. You must not use raw types. Creating it as raw type changes all its methods to raw as well, thus withColumnMapping(String, String, Function<String, Object>) becomes withColumnMapping(String, String, Function) and type of your lambda argument cannot be inferred. To fix your problem specify the proper generic arguments when calling the constructor.

like image 142
Tagir Valeev Avatar answered Sep 21 '22 21:09

Tagir Valeev