Issue
items
is a List<List<String>>
. When I add reversed
, I see a compile error Cannot resolve method 'get' in 'Object'
. I get this on x.get(0)
. Why do I get this and how can I get the reverse order? I would just like to sort the list based on the item name.
List<List<String>> items = new ArrayList<>();
List<String> item2 = new ArrayList<>();
item2.add("item2");
item2.add("3");
item2.add("4");
List<String> item1 = new ArrayList<>();
item1.add("item1");
item1.add("10");
item1.add("15");
List<String> item3 = new ArrayList<>();
item3.add("item3");
item3.add("17");
item3.add("8");
items.add(item1);
items.add(item2);
items.add(item3);
items.stream().sorted(Comparator.comparing(x -> x.get(0)).reversed()).collect(Collectors.toList())
Solution
Java's type inference fails here. When running Comparator.comparing(x -> x.get(0)).reversed()
, it is not able to infer the types of the Comparator
from the return type because of the .reversed()
. Since they cannot be inferred, Java just uses Object
.
In order to fix that, you need to somehow specify the type that is compared.
This can be done explicitly with Comparator.<List<String>, String>> comparing(x->x.get(0)).reversed()
. Here, List<String>, String>
are type arguments for the Comparator.comparing
call. This means they specify the values of the generic types at compile-time so they don't have to be inferred. The first type parameter (List<String>
) is the type to compare and second parameter (String
) is the Comparable
that is extracted from the type to compare (the result of List#get
).
Alternatively, you could also specify it in the lambda expression's parameters and let Java infer it from that: Comparator.comparing((List<String> x) -> x.get(0)).reversed()
. Since Java knows that x
is of the type List<String>
, it is able to infer the type of the lambda (Function<List<String>,String>
) and the Comparator.comparing
method.
When Sequenced Collections are added to Java, you could also use use method references. If you use Comparator.comparing(List::getFirst).reversed()
, Java knows that the type to compare is a List
and is able to use the get
method. Note that List::getFirst
is not yet part of the JDK as of the time of writing this.
As @Slaw mentioned in the comments, you could also use an entirely different approach by getting rid of the .reversed
and including it in the Comparator.comparing
like this: Comparator.comparing(x -> x.get(0), Comparator.reverseOrder())
. The second parameter is another Comparator
that is used for comparing the values extracted from the lambda x -> x.get(0)
.
Answered By - dan1st
Answer Checked By - David Marino (JavaFixing Volunteer)