Recently I was working with the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Test { public static void main(String[] args) { List<String> strings = new ArrayList<>(); List<Item> items = strings.stream().map(item -> new Item(new HashMap())).collect(Collectors.toList()); } } class Item { public Map<String, String> metadata; Item(Map<String, String> metadata) { this.metadata = metadata; } } |
I was compiling it with
1 2 3 |
java version "1.8.0_221" Java(TM) SE Runtime Environment (build 1.8.0_221-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode) |
on Windows 10 x64. It wasn’t working because of the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/tmp/java_fR1LWz/Test.java:10: warning: [unchecked] unchecked method invocation: constructor <init> in class Item is applied to given types List<Item> items = strings.stream().map(item -> new Item(new HashMap())).collect(Collectors.toList()); ^ required: Map<String,String> found: HashMap /tmp/java_fR1LWz/Test.java:10: warning: [unchecked] unchecked conversion List<Item> items = strings.stream().map(item -> new Item(new HashMap())).collect(Collectors.toList()); ^ required: Map<String,String> found: HashMap /tmp/java_fR1LWz/Test.java:10: warning: [unchecked] unchecked method invocation: method map in interface Stream is applied to given types List<Item> items = strings.stream().map(item -> new Item(new HashMap())).collect(Collectors.toList()); ^ required: Function<? super T,? extends R> found: Function<String,Item> where T,R are type-variables: T extends Object declared in interface Stream R extends Object declared in method <R>map(Function<? super T,? extends R>) /tmp/java_fR1LWz/Test.java:10: warning: [unchecked] unchecked call to <R,A>collect(Collector<? super T,A,R>) as a member of the raw type Stream List<Item> items = strings.stream().map(item -> new Item(new HashMap())).collect(Collectors.toList()); ^ where R,A,T are type-variables: R extends Object declared in method <R,A>collect(Collector<? super T,A,R>) A extends Object declared in method <R,A>collect(Collector<? super T,A,R>) T extends Object declared in interface Stream /tmp/java_fR1LWz/Test.java:10: error: incompatible types: Object cannot be converted to List<Item> List<Item> items = strings.stream().map(item -> new Item(new HashMap())).collect(Collectors.toList()); ^ 1 error 4 warnings |
You can try reproducing the issue at compilejava.net, it throws the error at the moment.
I was almost sure that it was a bug in javac, especially that the code was working fine in Java 12 as indicated by Ideone.
Fortunately, with some help from 4programmers.net community I was finally pointed out in the right direction. It is a bug and Oracle knows about that. You can see details at Oracle page.
Takeaway is: most of the time the problem is on the user side, compiler/platform/OS/library/CPU works well. However, sometimes one just hits a bug.