IsteveI
IsteveI

Reputation: 19

Compilation error when sorting a stream using a method reference

I want to sort my list of objects. I want to compare the Attribute elements by their names and compare the integer variable number of each object.

Below there is my code. I commented the line which doesn't work. How can I sort by the variable name of the non-primitive attribute Attribute of my Object?

List<Object> objects
List<Object> sortedObjects = objects.stream()
          .sorted(Comparator.comparing(Object::getAtt().getName)) //this doesn't work.
          .sorted(Comparator.comparing(Object::getNumber))
          .collect(Collectors.toList());

public class Object {
    Attribute att;
    int number;
    
    public Attribute getAtt() {
        return att;
    }
    public int getNumber() {
        return number;
    }

}

public class Attribute {
    String name;

    public String getName() {
        return name;
    }

}

Upvotes: -1

Views: 729

Answers (2)

M. Justin
M. Justin

Reputation: 21055

In addition to the compilation problem that Object::getAtt().getName should instead be o -> o.getAtt().getName() (addressed by this answer), the sorting is not implemented correctly.

By having two different sorted operations on the stream, the second sort operation will override the first (except in cases where the second operation yields a tie, in which case the first sort's relative ordering will be retained). It would be better to have a single sorted operation that sorts all elements as desired:

List<Object> sortedObjects = objects.stream()
        .sorted(Comparator.<Object, String>comparing(o -> o.getAtt().getName())
                .thenComparing(Object::getNumber))
        .collect(Collectors.toList());

Upvotes: 0

rzwitserloot
rzwitserloot

Reputation: 102795

Object::getAtt().getName

This isn't a thing. o -> o.getAtt().getName() is what you're looking for, I think.

Upvotes: 2

Related Questions