1

I was going through this question - this triggered the following set of thoughts regarding the Type Inference:

class Song {
  public Integer duration;
  public String artist;
  public String title;
//   ... getters...
}

List<Song> playlist1 = new ArrayList<>();

Collections.sort(Collections.EMPTY_LIST,
        Comparator.comparing((Song p1) -> p1.getTitle())); //-----1

Collections.sort(playlist1,
        Comparator.comparing(p1 -> p1.getTitle())); //----2

Collections.sort(playlist1,
        Comparator.comparing(p1 -> p1.getTitle())
            .thenComparing(p1 -> p1.getDuration()).thenComparing(p1 -> p1.getArtist()));
//----3
  1. Collections.sort(..) is not a Poly Expression but a Standalone Expression:
    • as the return type of .sort(...) is void - and the foremost conditions for this to be applicable for method invocation is that its return type must be Type Parameter that also appears in the arguments.
    • and method invocation must occur in the assignment/invocation context
  2. Comparator.comparing(...) : is a Poly Expression as:
    • it occurs in the invocation context and
    • has a return type that is a Type Argument also occurring as the arguments to the method.
  3. Thus in,Collections.sort(playlist1, Comparator.comparing(p1 -> p1.getTitle())); the expression Comparator.comparing(p1 -> p1.getTitle()) undergoes the type inference as:
    • Since the target type is Comparator<Song>
    • Comparator.comparing(...) will use the Target Type to determine the type arguments
    • and thus infers that p1 is of type Song.
  4. but if we consider Expression-3 we will see Compilation Error as:
    • Comparator.comparing(...).thenComparing(...).thenComparing(...) - has a target type of Comparator<Song>
    • this is because for an invocation chain of this type: ClassType.A().B().C() the inference will have to proceed from C() -> B() -> A() -> ClassType
    • now the problem is that for the compiler - it is complete unknown that which class is C() belonging to and hence will not be able to infer the chain upto A.
    • On the contrary - if the chain had been ClassType.A() - the compiler can easily determine that A() belongs to ClassType.
    • and thus the compiler is unable to determine the p1 and so on.

Is my thinking about the above points correct? or am I missing something?

theutonium.18
  • 483
  • 2
  • 7

0 Answers0