3

Here is the situation: We have a Student object which contains courseId as one of its fields. I want to return true if there is any student with course in history.

List<Student> students = new ArrayList();
students.stream.anyMap(s -> getFromDataBase(s.getCourseId()).name == "History");

Now, there is an optimization to prevent DB calls. Since many students can have the same courseId, it makes sense to filter out redundant courseId.

Eg:

List<Student> students = new ArrayList();
Set<Id> course = new HashSet<>();
for (Student s : students) {
    course.add(s.getCourseId());  
}

course.stream.anyMap(s -> getFromDataBase(s.getCourseId()).name == "History");

Now is there some way in Java-8, which I can use so that I don't need to do the following stuff:

  Set<Id> course = new HashSet<>();
    for (Student s : students) {
        course.add(s.getCourseId());  
    }
4
  • What you have above is perfectly fine in Java 8. Commented Aug 17, 2017 at 21:07
  • @JoeC although non-idiomatic Commented Aug 17, 2017 at 22:03
  • 2
    It looks like you could easily optimize this by searching by course id and name directly in database. At least you should avoid performing one query per course id and use a courseId in (courseId1, courseId2, …) Commented Aug 18, 2017 at 6:54
  • 1
    Totally agree with @DidierL - a single db query can do this for a much more significant performance gain. Commented Aug 18, 2017 at 11:21

3 Answers 3

3

Note: Remember to compare Strings with String#equals and not ==.

With Java 8, you don't even need to use a Set, as there exists distinct Streams:

List<Student> students = ...;

students.stream()
        .map(Student::getCourseId)
        .distinct()
        .map(this::getFromDataBase)
        .map(Database::getName)
        .anyMatch(s -> s.equals("History"));

Keep in mind that you have not provided the names of your classes, so I don't know how to map a database entry to its name, so you'll need to modify that.

Sign up to request clarification or add additional context in comments.

Comments

2

If you simply want to avoid duplication in a Java 8 idiom, you can utilize distinct() method:

students.stream()
  .map(s -> s.getCourseId())
  .distinct()
  // .. whatever

Comments

1

Is getFromDataBase() a DB call ? Then why not change your DB call to take the courseId as parameter to the DB call (stored procedure?) and return the students with the course in question.

This way, we don't need to worry about the distinct transformations you are looking for.

If you still want to convert List<Student> to Set<Id> then

List<Student> students = ....

Set<Id> studentsId = new HashSet<>(students.stream()
                                           .map(s -> s.courseId)
                                           .Collectors.toList());

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.