Search code examples
javalistclasssortingcomparator

Sort the list of objects by the field in included object


I want to sort the list of objects potentialHS by the distance in ElementWithDistance class but I can't get the distnace field in this way. After calling getElementWithDistance i can't call getDistance. How can I sort my list by the the field in included class?

List<PotentialHS> potentialHS = potentialHS.stream().sorted(Comparator.comparingDouble(PotentialHS :: getElementWithDistance)).collect(Collectors.toList());

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@ToString
public class PotentialHS {
    private Integer density;
    private Double startDistance;
    private Double lastDistance;
    private List<PMValue> pmv;
    private ElementWithDistance elementWithDistance;
}

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@ToString
public class ElementWithDistance  {
    private Long elementId;
    private Double distance;
    private Type type;
}

Solution

  • PotentialHS :: getElementWithDistance
    

    is shorthand for:

    (PotentialHS x) -> x.getElementWithDistance()
    

    In other words, it says: To sort this stream, applying the following operation:

    • Per item in the stream, fetch the thing you get by invoking getElementWithDistance() on it. Treat that as a double, then sort by those doubles.

    Which obviously won't work - ElementWithDistance is not a double.

    You want:

    (PotentialHS x) -> x.getElementWithDistance().getDistance();
    

    Note also how that is a Double, not a double, so that's a mistake (fix it. Double is the non-primitive wrapper type around double, and you really don't want it. It has an extra value (null), and is grievously inefficient. It also means you can't do things like 'give me the largest double in this stream'.

    This gets you:

    List<PotentialHS> potentialHS = potentialHS.stream().sorted(Comparator.comparingDouble(x -> x.getElementWithDistance().getDistance())).collect(Collectors.toList());