Search code examples
javasortingcollectionsjava-streamcomparator

How to sort the list of object what contains the list that contain also the list of object in Java?


I have the list of object of the "MainClass" class that contains the list of objects Of the "Question" class, that contains the list of objects of the Option class. How I can sort the list of "MainClass" class by its "Id" and "Option" class By its "Id"?

public class MainClass {
    private Long id;
    private List<Question> questions;
}

public class Question {
    private Set<Option> options;
}

public class Option{
    private Long id;
}

Assume, List<MainClass> result = data; I tried next:

result.stream().sorted(Comparator.comparing(MainClass::getId)).map(qc->qc.getQuestions()).flatMap(List::stream).map(q->q.getOptions()).flatMap(Set::stream).sorted(Comparator.comparing(Option::getId)).collect(Collectors.toList());

As a result I should get the sorted List<MainClass> class by MainClass "Id" and "Option" class By its "Id"

I write sample/prototype of source of code:

public class MainClass {
    private Long id;
    private List<Question> questions;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public List<Question> getQuestions() {
        return questions;
    }

    public void setQuestions(List<Question> questions) {
        this.questions = questions;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MainClass mainClass = (MainClass) o;
        return Objects.equals(id, mainClass.id) && Objects.equals(questions, mainClass.questions);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, questions);
    }
}


 class Question {
    private Set<Option> options;

     public Set<Option> getOptions() {
         return options;
     }

     public void setOptions(Set<Option> options) {
         this.options = options;
     }

     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
         Question question = (Question) o;
         return Objects.equals(options, question.options);
     }

     @Override
     public int hashCode() {
         return Objects.hash(options);
     }
 }

 class Option{
    private Long id;

     public Long getId() {
         return id;
     }

     public void setId(Long id) {
         this.id = id;
     }

     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
         Option option = (Option) o;
         return Objects.equals(id, option.id);
     }

     @Override
     public int hashCode() {
         return Objects.hash(id);
     }
 }

class Test{
    public static void main(String[] args) {
        Option option = new Option();
        option.setId(3L);
        Option option2 = new Option();
        option2.setId(2L);
        Option option3 = new Option();
        option3.setId(1L);

        Question question = new Question();
        question.setOptions(Set.of(option));
        Question question2 = new Question();
        question2.setOptions(Set.of(option2, option3));
        Question question3 = new Question();
        question3.setOptions(Set.of(option3));
        
        MainClass mc = new MainClass();
        mc.setId(1L);
        mc.setQuestions(List.of(question,question3));
        
        MainClass mc2 = new MainClass();
        mc2.setId(2L);
        mc2.setQuestions(List.of(question,question2));
        
        List<MainClass> list  = new LinkedList<>();
        list.add(mc);
        list.add(mc2);
    }
}

Solution

  • Below method will sort as per the requirement :

    public List<MainClass> sort(List<MainClass> list) {
        List<MainClass> sorted = list.stream()
                .map(t -> {
                    t.questions.stream().forEach(t1 -> {
                        t1.options = t1.options.stream().sorted(Comparator.comparing(o -> o.id)).collect(Collectors.toSet());
                    });
                    return t;
                })
                .sorted(Comparator.comparing(o -> o.id))
                .collect(Collectors.toList());
        return sorted;
    }