0

I'm fairly new to Java8. I have a requirement to convert List of plain objects to group by a certain criteria and show it on UI.

  • The key to the map should be combination of "fromDate-todate" and the list of students should be associated to this combination.
  • Also, the 'ClassOfMsSwan' object needs to be converted to 'Student' object and saved into the list.
  • Code for Java1.7 has been written and needs to be converted to Java1.8.

Kindly help me out.

public class ClassOfMsSwan {

private String fromDate;
private String toDate;
private String studentName;
private String subject;
private String marks;

public ClassOfMsSwan(String fromDate, String toDate, String studentName, String subject, String marks) {
    super();
    this.fromDate = fromDate;
    this.toDate = toDate;
    this.studentName = studentName;
    this.subject = subject;
    this.marks = marks;
}
// setters and getters


public class Student {

private String name;
private String subject;
private String marks;
public Student(String name, String subject, String marks) {
    this.marks = marks;
    this.subject = subject;
    this.name = name;
}   
// setters and getters




List<ClassOfMsSwan> classes = new ArrayList<>();

    ClassOfMsSwan classOfMsSwan1 = new ClassOfMsSwan("06/01/2016", "05/31/2017", "David", "Physics", "98");
    ClassOfMsSwan classOfMsSwan2 = new ClassOfMsSwan("06/01/2016", "05/31/2017", "Jane", "Botany", "85");
    ClassOfMsSwan classOfMsSwan3 = new ClassOfMsSwan("06/01/2016", "05/31/2017", "Mathew", "Algebra", "76");

    ClassOfMsSwan classOfMsSwan4 = new ClassOfMsSwan("06/01/2017", "05/31/2018", "David", "Geometry", "94");
    ClassOfMsSwan classOfMsSwan5 = new ClassOfMsSwan("06/01/2017", "05/31/2018", "Jane", "Organic Chemistry", "92");
    ClassOfMsSwan classOfMsSwan6 = new ClassOfMsSwan("06/01/2017", "05/31/2018", "Mathew", "Botany", "100");

    ClassOfMsSwan classOfMsSwan7 = new ClassOfMsSwan("06/01/2018", "05/31/2019", "Mathew", "Geometry", "86");
    ClassOfMsSwan classOfMsSwan8 = new ClassOfMsSwan("06/01/2018", "05/31/2019", "Jane", "Algebra", "84");

    classes.add(classOfMsSwan1);
    classes.add(classOfMsSwan2);
    classes.add(classOfMsSwan3);
    classes.add(classOfMsSwan4);
    classes.add(classOfMsSwan5);
    classes.add(classOfMsSwan6);
    classes.add(classOfMsSwan7);
    classes.add(classOfMsSwan8);

    // JDK1.7
    Map<String, List<Student>> dateStudentMap = new HashMap<>();
    for(ClassOfMsSwan classOfMsSwan : classes) {
        List<Student> students = dateStudentMap.get(classOfMsSwan.getFromDate() + "-" + classOfMsSwan.getToDate());
        if(CollectionUtils.isEmpty(students)) {
            students = new ArrayList<>();
            dateStudentMap.put(classOfMsSwan.getFromDate() + "-" + classOfMsSwan.getToDate(), students);
        }
        students.add(new Student(classOfMsSwan.getStudentName(), classOfMsSwan.getSubject(), classOfMsSwan.getMarks()));
    }


Desired output
   {06/01/2016-05/31/2017=[Student [name=David, subject=Physics, marks=98], Student [name=Jane, subject=Botany, marks=85], Student [name=Mathew, subject=Algebra, marks=76]], 06/01/2017-05/31/2018=[Student [name=David, subject=Geometry, marks=94], Student [name=Jane, subject=Organic Chemistry, marks=92], Student [name=Mathew, subject=Botany, marks=100]], 06/01/2018-05/31/2019=[Student [name=Mathew, subject=Geometry, marks=86], Student [name=Jane, subject=Algebra, marks=84]]}
1
  • 2
    Have a look at Collectors Javadoc. It also contains examples and convenience methods to get you started. Commented Oct 10, 2017 at 7:38

1 Answer 1

3

You can achieve this use Java 8 API like this:

Map<String, Set<Student>> dateStudentMap = classes.stream().map(e ->  
                new Entry(e.getFromDate() + "-" + e.getToDate(),
                        new Student(e.getStudentName(), e.getSubject(), e.getMarks())
            ))
    .collect(groupingBy(Entry::getKey, TreeMap::new,
            mapping(Entry::getValue, toSet())));

where I use a primitive helper class Entry defined like below:

class Entry{
    public Entry(String key, Student value){
        this.setKey(key);
        this.setValue(value);
    }
    //getters and setters

    private String key;
    private Student value;
}

Hope that helps.

EDIT:

Acorrding to Holger's comment (it is much better):

    Map<String, Set<Student>> dateStudentMap8 = classes.stream()
            .collect(groupingBy(e -> 
                        e.getFromDate() + "-" + e.getToDate(),
                        mapping(e -> 
                            new Student(e.getStudentName(), 
                                        e.getSubject(), 
                                        e.getMarks()), 
                            toSet())));
Sign up to request clarification or add additional context in comments.

3 Comments

There is no need for this Entry helper class. Just use classes.stream() .collect(groupingBy(e -> e.getFromDate() + "-" + e.getToDate(), mapping(e -> new Student(e.getStudentName(), e.getSubject(), e.getMarks()), toSet()))); It’s also unclear why you enforce the use of a TreeMap when the OP clearly used a HashMap
Your comment is a much better answer, I edited mine according to it, thanks!
Thank you ! This is what exactly what I wanted !

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.