0

I have classes structure similar to:

    class FinalResponse {
        Source source;
        List<Target> targets;
    }
    
    class Response {
    Source source;
    Target target;
   }

    class Source {
        Long sourceId;
        String sourceName;
    }
    
    class Target {
        Long targetId;
        String targetName;
    }

I have two different tables Source and Target, and after joining them I am getting four columns in the query output. I am constructing Response object using values of these four columns. I have data in Response object with these 4 properties sourceId, sourceName, targetId, targetName. I can have sourceId, sourceName same on the multiple rows but targetId, targetName will always be different.

I grouped all the target objects into the List for which source is the same.

List<FinalResponse> finalResponses = responses.stream()
    .collect(Collectors.groupingBy(
        Response::getSource,
        LinkedHashmap::new,
        Collectors.mapping(Response::getTarget, Collectors.toList())
    )) // Map<Source, List<Target>> is built
    .entrySet()
    .stream() // Stream<Map.Entry<Source, List<Target>>>
    .map(e -> new FinalResponse(e.getKey(), e.getValue()))
    .collect(Collectors.toList());

But sometimes reponse from database cannot be sorted and even though it is sorted and I have used LinkedHashmap::new then also my final output List<FinalResponse> finalResponses is not sorted. I wanted my final output to be sorted as per sourceId, so I did:

finalResponses.sort(Comparator.comparing(finalResponse->finalResponse.getSource().getSourceId()));

It is working fine for non null values but if I have source(sourceId=null,sourceName=null) on multiple rows then I am getting NullPointerException. What is the best approach to Sort Collection based on Source Object's sourceId property ?

4
  • 2
    Are the null source fields acceptable in your problem domain, or is that a problem/bug? And if you do allow null source data, how do you expect to use Source as a key in a map? Commented Dec 25, 2021 at 10:13
  • @basil-bourque It is not the problem, it is allowed sometimes. For certain cases there could be targets without the source. Map is getting constructed properly with null as a key, I have taken care of equals and hashcode in both Source and Target classes. Commented Dec 25, 2021 at 10:21
  • Does this answer your question? Java 8 sort on Class member's property Commented Dec 25, 2021 at 10:31
  • @tgdavies as I have posted, I have tried similar approach but it is not working for null values. Commented Dec 25, 2021 at 10:36

1 Answer 1

2

Comparator.nullsLast or Comparator.nullsFirst should be applied to handle possible null values in the compared items:

finalResponses.sort(Comparator.nullsLast(
    Comparator.comparing(fr -> fr.getSource().getSourceId())
));

or like this:

finalResponses.sort(Comparator.comparing(
    fr -> fr.getSource().getSourceId(),
    Comparator.nullsLast(Comparator.naturalOrder())
));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.