Eclipse does not suggest methods in Lambda expression

Tags: ,



I have an ArrayList of Strings, and am adding a method to sort the ArrayList

list.sort(Comparator.comparing(x -> x.length()));

When I write x and press ctrl + space eclipse does not suggest the methods of the String class, but only shows methods of the Object class.
enter image description here

Please help me configure eclipse to show the exact method suggestions in this case. In regular cases eclipse is exact.

Answer

This is a two-fold issue, one with eclipse, and one with java semantics.

Java Semantics

A quick example:

public static void main(String[] args) {
    List<String> myList = new ArrayList<>();
    myList.sort(Comparator.comparing(x -> x.|));
}

Assume you press ctrl + space at the | (cursor) position. Then eclipse has to infer a lot of information to know, that x is in fact an element of type String. First, the list’s generic type String must be known (it is, eclipse can deduce this). Then the Comparator.comparing method needs to know, that it must return an instance of a Comparator which compares Strings, which eclipse could deduce, but here is the first issue: The Comparator could be one that compares not just Strings, but also any other kind of Object. What if you wanted to pass a method to myList.sort that is more general than the generic Comparator<String>? To be more precise: The List.sort method can take (in your case) any Comparator of type Comparator<? super String>. And ? super String is already either Object or String. So in your example. the type of x could just be an object, eclipse cannot ultimately decide. However, you can write your lambda expression differently, to make it clear:

myList.sort(Comparator.comparing((String x) -> x.|));

In this case, the completion suggestion could be more helpful (depending on the version of eclipse).

eclipse AST issues with incomplete lambdas

An incomplete lambda expression is more often than not such an upset in the syntax of the entire file, that eclipse cannot determine the syntax tree at that position correctly. That means, that eclipse cannot deduce, that the code you are writing is supposed to be a lambda expression, where x is the parameter of the lambda function, and you want to complete that. This issue could be addressed, if the tokenizer and AST-parser of eclipse are adapted accordingly (which might have already been tried). Whether this is possible at all, I cannot answer. I only know it helps, to write a “full” lambda, with a method block, and convert that to a “slim” lambda later on:

myList.sort(Comparator.comparing((String x) -> { return x.| }));

For the above case, the completion should work (IF you specify String as absolute type of the Comparator, as I have done in the example).

Issues like this stem from the question of how to interpret the characters and therefore deduce, what the programmer might intent to write (the process of auto completion and completion suggestion). eclipse is very strong in isolating a reference to a named entity, when in regular code, like a method block, a for loop, or any other construct. That is why it works well there. The syntax tree is usually easy to process then.

However when using lambdas, eclipse (and any other IDE for that matter) have a harder time. This is due to the fact, that lambdas work by inferring a lot of implicit information, which would otherwise need to be written explicitly (for example in an explicit implementation of the interface).

If everything else fails, you can create the explicit interface at that position and then convert to a lambda after completing it.



Source: stackoverflow