From 7033900d839d6651f949f7dbe91c9e77175c9c9d Mon Sep 17 00:00:00 2001 From: "Dr. Martin Goik" <goik@hdm-stuttgart.de> Date: Fri, 12 Oct 2018 17:04:28 +0200 Subject: [PATCH] Implementation hints --- .../mi/javastreams/Java8FunctionalTest.java | 99 ++++++--- .../mi/javastreams/RosterTest.java | 202 ++++++++---------- .../hdm_stuttgart/mi/javastreams/Student.java | 49 +---- .../mi/javastreams/Java8FunctionalTest.java | 37 +++- 4 files changed, 182 insertions(+), 205 deletions(-) diff --git a/P/Sda1/Streams/Solution/src/test/java/de/hdm_stuttgart/mi/javastreams/Java8FunctionalTest.java b/P/Sda1/Streams/Solution/src/test/java/de/hdm_stuttgart/mi/javastreams/Java8FunctionalTest.java index 39a44d258..2e9430d4c 100644 --- a/P/Sda1/Streams/Solution/src/test/java/de/hdm_stuttgart/mi/javastreams/Java8FunctionalTest.java +++ b/P/Sda1/Streams/Solution/src/test/java/de/hdm_stuttgart/mi/javastreams/Java8FunctionalTest.java @@ -11,38 +11,47 @@ import java.util.stream.Collectors; import org.hamcrest.Matchers; import org.junit.Assert; +import org.junit.FixMethodOrder; import org.junit.Test; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import de.hdm_stuttgart.mi.javastreams.Student.Sex; +import org.junit.runners.MethodSorters; /** * Testing functional queries. */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) public class Java8FunctionalTest { - final List<Student> roster = Student.createRoster(); + static private final List<Student> students = ImmutableList.of( + new Student("Fred", 2, Student.Sex.MALE, "fred@example.com") + ,new Student("Jane", 1, Student.Sex.FEMALE, "jane@kiv.de") + ,new Student("George", 4, Student.Sex.MALE, "george@math.edu") + ,new Student("Bob", 2, Student.Sex.MALE, "bob@uk.edu") + ,new Student("Kim", 2, Student.Sex.FEMALE, "wilde@serious.de") + ); - /** - * Order all male students by email and create a list of their respective names - * in that order eliminating possible duplicates: - * - * "Bob", 2, Student.Sex.MALE, "bob@uk.edu" - * "Fred", 2, Student.Sex.MALE, "fred@example.com" - * "George", 4, Student.Sex.MALE, "george@math.edu" - * "Jane", 1, Student.Sex.FEMALE, "jane@kiv.de" - * "Kim", 2, Student.Sex.FEMALE, "wilde@serious.de" - * - * ==> {"Bob", "Fred", "George"} - * - */ + /** + * <p>Order all male students by email and create a {@code List<String>} of their respective + * names alphabetically ordered eliminating possible duplicates. Implementation hints:</p> + * + * <pre + * >"Fred", 2, Student.Sex.MALE, "fred@example.com" + * "Jane", 1, Student.Sex.FEMALE, "jane@kiv.de" + * "George", 4, Student.Sex.MALE, "george@math.edu" + * "Bob", 2, Student.Sex.MALE, "bob@uk.edu" + * "Kim", 2, Student.Sex.FEMALE, "wilde@serious.de"</pre> + * + * <p>Result: {"Bob", "Fred", "George"}</p> + */ @Test public void allMaleDistinctNameOrderedByEmail() { final List<String> emails = - roster.parallelStream(). + students.parallelStream(). filter(s -> s.gender == Sex.MALE). sorted((s1, s2) -> s1.getEmailAddress().compareTo(s2.getEmailAddress())). map(Student::getName). @@ -57,18 +66,42 @@ public class Java8FunctionalTest { ); } - /** - * Summing students' marks having a German email address: - * - * "Jane", 1, Student.Sex.FEMALE, "jane@kiv.de" - * "Kim", 2, Student.Sex.FEMALE, "wilde@serious.de" - * - */ + /** + * <p>Summing up all students' marks having a German email address.</p> + * + * <dl> + * + * <dt>List of all students having a german E-mail:</dt> + * <dd> + * <ul> + * <li><code>{"Jane", 1, Student.Sex.FEMALE, "jane@kiv.de"}</code></li> + * <li><code>{"Kim", 2, Student.Sex.FEMALE, "wilde@serious.de"}</code></li> + * </ul> + * </dd> + * + * <dt>Summing up related marks:</dt> + * <dd>Expected value: 1 + 2 == 3</dd> + * </dl> + * + * <p>Implementation hint: Process a stream of Student instances by:</p> + * + * <ol> + * <li>Filter students having a german email.</li> + * <li>Map objects to int.</li> + * <li>Provide a suitable + * <a href="https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html#reduce" + * >reduce operation</a>. You may safely assume the existence of at least one Student.</li> + * </ol> + * + * <p>You may want to read + * <a href="https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html#reduce" + * >https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html#reduce</a>.</p> + */ @Test public void markSumAllStudentsMarksHavingEmail_Dot_de() { Assert.assertEquals( 3, //Expected marks sum 3 == 1 + 2 - roster.parallelStream() + students.parallelStream() .filter(p -> p.emailAddress.endsWith(".de")) // Jane and Kim .mapToInt(Student::getMark) .reduce(0, (a, b) -> a + b) @@ -76,8 +109,8 @@ public class Java8FunctionalTest { } /** - * A comma separated string containing all students' alphabetically ordered - * email addresses: + * <p>A comma separated string containing all students' alphabetically ordered + * email addresses:</p> * * "bob@uk.edu, fred@example.com, george@math.edu, ..." * @@ -88,7 +121,7 @@ public class Java8FunctionalTest { Assert.assertEquals( "bob@uk.edu, fred@example.com, george@math.edu, jane@kiv.de, wilde@serious.de", - roster.parallelStream(). + students.parallelStream(). map(Student::getEmailAddress). sorted(). collect(new CsvCollector(", ")) // Using ", " as separator string. @@ -110,7 +143,7 @@ public class Java8FunctionalTest { Assert.assertEquals( "bob@uk.edu, fred@example.com, george@math.edu, jane@kiv.de, wilde@serious.de", - roster.parallelStream(). + students.parallelStream(). map(Student::getEmailAddress). sorted(). collect @@ -134,7 +167,7 @@ public class Java8FunctionalTest { public void averageMarkFemaleStudents() { final OptionalDouble femaleAverage = - roster.parallelStream(). + students.parallelStream(). filter(s -> s.gender == Sex.FEMALE). mapToInt(Student::getMark). average(); @@ -161,7 +194,7 @@ public class Java8FunctionalTest { public void studentNamesBySex() { final Map<Student.Sex, List<String>> studentnamesBySex = - roster + students .parallelStream() .collect( Collectors.groupingBy( @@ -187,14 +220,14 @@ public class Java8FunctionalTest { * Marking frequencies: * * Mark 1: "Jane" --- 1 student - * Mark 2: "Fred", "Bob", "Kim" --> 3 students - * Mark 4: "George" --> 1 student + * Mark 2: "Fred", "Bob", "Kim" --- 3 students + * Mark 4: "George" --- 1 student * */ @Test public void markingFrequencies() { final Map<Integer, Integer> frequencyByMark = - roster + students .parallelStream() .collect( Collectors.groupingBy( @@ -229,7 +262,7 @@ public class Java8FunctionalTest { public void studentnamessByMark() { final Map<Integer, List<String>> namesByMark = - roster + students .parallelStream() .collect( Collectors.groupingBy( diff --git a/P/Sda1/Streams/Template/src/main/java/de/hdm_stuttgart/mi/javastreams/RosterTest.java b/P/Sda1/Streams/Template/src/main/java/de/hdm_stuttgart/mi/javastreams/RosterTest.java index 4bee36942..09b4b611c 100644 --- a/P/Sda1/Streams/Template/src/main/java/de/hdm_stuttgart/mi/javastreams/RosterTest.java +++ b/P/Sda1/Streams/Template/src/main/java/de/hdm_stuttgart/mi/javastreams/RosterTest.java @@ -1,5 +1,8 @@ package de.hdm_stuttgart.mi.javastreams; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + import java.util.List; import java.util.function.Consumer; import java.util.function.Function; @@ -10,111 +13,108 @@ import java.util.function.Predicate; * https://docs.oracle.com/javase/tutorial/java/javaOO/examples/Person.java * and * https://docs.oracle.com/javase/tutorial/java/javaOO/examples/RosterTest.java - * */ public class RosterTest { - - static final List<Student> rosterInstance = Student.createRoster(); - + + static final List<Student> students = ImmutableList.of( + new Student("Fred", 2, Student.Sex.MALE, "fred@example.com") + ,new Student("Jane", 1, Student.Sex.FEMALE, "jane@kiv.de") + ,new Student("George", 4, Student.Sex.MALE, "george@math.edu") + ,new Student("Bob", 2, Student.Sex.MALE, "bob@uk.edu") + ,new Student("Kim", 2, Student.Sex.FEMALE, "wilde@serious.de") + ); + + interface CheckStudent { boolean test(Student p); } - // Approach 1: Create Methods that Search for Persons that Match One - // Characteristic - /** + * Approach 1: Create Methods that searching for Persons matching one characteristic + * * @param roster * @param mark */ - public static void printPersonsOlderThan(List<Student> roster, int mark) { - for (Student p : roster) { + public static void printPersonsOlderThan(final List<Student> roster, final int mark) { + for (final Student p : roster) { if (p.getMark()>= mark) { p.print(); } } } - // Approach 2: Create More Generalized Search Methods - /** + * Approach 2: Create more generalized search methods + * * @param roster * @param low * @param high */ - public static void printPersonsWithinMarkRange( - List<Student> roster, int low, int high) { - for (Student p : roster) { + public static void printPersonsWithinMarkRange(final List<Student> roster, final int low, final int high) { + for (final Student p : roster) { if (low <= p.getMark() && p.getMark() <= high) { p.print(); } } } - // Approach 3: Specify Search Criteria Code in a Local Class - // Approach 4: Specify Search Criteria Code in an Anonymous Class - // Approach 5: Specify Search Criteria Code with a Lambda Expression - /** + * Approach 3: Specify search criteria in a local class + * Approach 4: Specify search criteria by an anonymous class + * Approach 5: Specify search criteria by lambda expression + * * @param roster * @param tester */ - public static void printPersons( - List<Student> roster, CheckStudent tester) { - for (Student p : roster) { + public static void printPersons(final List<Student> roster, final CheckStudent tester) { + for (final Student p : roster) { if (tester.test(p)) { p.print(); } } } - // Approach 6: Use Standard Functional Interfaces with Lambda Expressions - /** + * Approach 6: Use standard functional interfaces employing lambda expressions. + * * @param roster * @param tester */ - public static void printPersonsWithPredicate( - List<Student> roster, Predicate<Student> tester) { - for (Student p : roster) { + public static void printPersonsWithPredicate(final List<Student> roster, final Predicate<Student> tester) { + for (final Student p : roster) { if (tester.test(p)) { p.print(); } } } - // Approach 7: Use Lambda Expressions Throughout Your Application - /** + * Approach 7: Use lambda expressions throughout your application + * * @param roster * @param tester * @param block */ - public static void processPersons( - List<Student> roster, - Predicate<Student> tester, - Consumer<Student> block) { - for (Student p : roster) { + public static void processPersons(final List<Student> roster, final Predicate<Student> tester, + final Consumer<Student> block) { + for (final Student p : roster) { if (tester.test(p)) { block.accept(p); } } } - // Approach 7, second example - /** + * Approach 7, second example + * * @param roster * @param tester * @param mapper * @param block */ - public static void processPersonsWithFunction( - List<Student> roster, - Predicate<Student> tester, - Function<Student, String> mapper, - Consumer<String> block) { - for (Student p : roster) { + public static void processPersonsByFunction(final List<Student> roster, final Predicate<Student> tester, + final Function<Student, String> mapper, final Consumer<String> block) { + for (final Student p : roster) { if (tester.test(p)) { String data = mapper.apply(p); block.accept(data); @@ -122,25 +122,22 @@ public class RosterTest { } } - // Approach 8: Use Generics More Extensively - /** + * Approach 8: Use Generics more extensively + * * @param source * @param tester * @param mapper * @param block */ - public static <X, Y> void processElements( - Iterable<X> source, - Predicate<X> tester, - Function<X, Y> mapper, - Consumer<Y> block) { - for (X p : source) { - if (tester.test(p)) { - Y data = mapper.apply(p); - block.accept(data); - } + public static <X, Y> void processElements( final Iterable<X> source, final Predicate<X> tester, + final Function<X, Y> mapper, final Consumer<Y> block) { + for (final X p : source) { + if (tester.test(p)) { + Y data = mapper.apply(p); + block.accept(data); } + } } /** @@ -148,27 +145,21 @@ public class RosterTest { */ public static void main(String... args) { - for (Student p : rosterInstance) { + System.out.println("All student records:"); + for (final Student p : students) { p.print(); } - // Approach 1: Create Methods that Search for Persons that Match One - // Characteristic - - System.out.println("Persons older than 20:"); - printPersonsOlderThan(rosterInstance, 20); - System.out.println(); - - // Approach 2: Create More Generalized Search Methods - - System.out.println("Persons between the ages of 14 and 30:"); - printPersonsWithinMarkRange(rosterInstance, 14, 30); - System.out.println(); + // Approach 1: Create methods searching for students matching one characteristic + System.out.println("\nApproach 1: Persons older than 20:"); + printPersonsOlderThan(students, 20); - // Approach 3: Specify Search Criteria Code in a Local Class - - System.out.println("Persons who are eligible for Selective Service:"); + // Approach 2: Create more generalized search methods + System.out.println("\nApproach 2: Persons between 14 and 30 of age:"); + printPersonsWithinMarkRange(students, 14, 30); + // Approach 3: Specify search criteria by a local class + System.out.println("\nApproach 3: Persons eligible for selective service:"); class CheckStudentEligibleForSelectiveService implements CheckStudent { @Override public boolean test(Student p) { @@ -177,23 +168,16 @@ public class RosterTest { && p.getMark() <= 3; } } + printPersons(students, new CheckStudentEligibleForSelectiveService()); - printPersons( - rosterInstance, new CheckStudentEligibleForSelectiveService()); - - - System.out.println(); - - // Approach 4: Specify Search Criteria Code in an Anonymous Class - - System.out.println("Persons who are eligible for Selective Service " + + // Approach 4: Specify search criteria code in an anonymous class + System.out.println("\nApproach 4: Persons eligible for selective service " + "(anonymous class):"); - printPersons( - rosterInstance, + students, new CheckStudent() { @Override - public boolean test(Student p) { + public boolean test(final Student p) { return p.getSex() == Student.Sex.MALE && p.getMark() >= 2 && p.getMark() <= 3; @@ -201,59 +185,46 @@ public class RosterTest { } ); - System.out.println(); - - // Approach 5: Specify Search Criteria Code with a Lambda Expression - - System.out.println("Persons who are eligible for Selective Service " + + // Approach 5: Specify search criteria by lambda expression + System.out.println("\nApproach 5: Persons eligible for selective service " + "(lambda expression):"); printPersons( - rosterInstance, + students, (Student p) -> p.getSex() == Student.Sex.MALE && p.getMark() >= 2 && p.getMark() <= 3 ); - System.out.println(); - - // Approach 6: Use Standard Functional Interfaces with Lambda - // Expressions - - System.out.println("Persons who are eligible for Selective Service " + + // Approach 6: Use Standard functional interfaces employing lambda expressions + System.out.println("\nApproach 6: Persons eligible for selective service " + "(with Predicate parameter):"); printPersonsWithPredicate( - rosterInstance, + students, p -> p.getSex() == Student.Sex.MALE && p.getMark() >= 18 && p.getMark() <= 25 ); - System.out.println(); - - // Approach 7: Use Lamba Expressions Throughout Your Application - - System.out.println("Persons who are eligible for Selective Service " + + // Approach 7: Using lamba expressions throughout + System.out.println("\nApproach 7: Persons eligible for selective service " + "(with Predicate and Consumer parameters):"); processPersons( - rosterInstance, + students, p -> p.getSex() == Student.Sex.MALE && p.getMark() >= 2 && p.getMark() <= 3, p -> p.print() ); - System.out.println(); - // Approach 7, second example - - System.out.println("Persons who are eligible for Selective Service " + + System.out.println("\nApproach 7, second example: Persons eligible for selective service " + "(with Predicate, Function, and Consumer parameters):"); - processPersonsWithFunction( - rosterInstance, + processPersonsByFunction( + students, p -> p.getSex() == Student.Sex.MALE && p.getMark() >= 2 && p.getMark() <= 3, @@ -261,15 +232,12 @@ public class RosterTest { email -> System.out.println(email) ); - System.out.println(); - - // Approach 8: Use Generics More Extensively - - System.out.println("Persons who are eligible for Selective Service " + + // Approach 8: Use generics more extensively + System.out.println("\nApproach 8: Persons eligible for selective service " + "(generic version):"); processElements( - rosterInstance, + students, p -> p.getSex() == Student.Sex.MALE && p.getMark() >= 2 && p.getMark() <= 3, @@ -277,15 +245,13 @@ public class RosterTest { email -> System.out.println(email) ); - System.out.println(); - - // Approach 9: Use Bulk Data Operations That Accept Lambda Expressions + // Approach 9: Using bulk data operations accepting lambda expressions // as Parameters - System.out.println("Persons who are eligible for Selective Service " + + System.out.println("\nApproach 9: Persons eligible for selective service " + "(with bulk data operations):"); - rosterInstance + students .stream() .filter( p -> p.getSex() == Student.Sex.MALE @@ -294,4 +260,4 @@ public class RosterTest { .map(p -> p.getEmailAddress()) .forEach(email -> System.out.println(email)); } -} +} \ No newline at end of file diff --git a/P/Sda1/Streams/Template/src/main/java/de/hdm_stuttgart/mi/javastreams/Student.java b/P/Sda1/Streams/Template/src/main/java/de/hdm_stuttgart/mi/javastreams/Student.java index 80c48c353..6ed4bfd58 100644 --- a/P/Sda1/Streams/Template/src/main/java/de/hdm_stuttgart/mi/javastreams/Student.java +++ b/P/Sda1/Streams/Template/src/main/java/de/hdm_stuttgart/mi/javastreams/Student.java @@ -1,56 +1,13 @@ package de.hdm_stuttgart.mi.javastreams; /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle or the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Loosely derived from https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html. */ -import java.util.Arrays; -import java.util.List; /** Representing students among with examination marks. */ public class Student { - /** @return Test sample of students. */ - public static List<Student> createRoster() { // Create test data records - - final Student[] roster = new Student[] { - new Student("Fred", 2, Student.Sex.MALE, "fred@example.com") - ,new Student("Jane", 1, Student.Sex.FEMALE, "jane@kiv.de") - ,new Student("George", 4, Student.Sex.MALE, "george@math.edu") - ,new Student("Bob", 2, Student.Sex.MALE, "bob@uk.edu") - ,new Student("Kim", 2, Student.Sex.FEMALE, "wilde@serious.de") - }; - - return Arrays.asList(roster); - } - /** Male or female */ public enum Sex { /** */ @@ -60,12 +17,12 @@ public class Student { final String extern; - private Sex(final String extern) {this.extern = extern;} + Sex(final String extern) {this.extern = extern;} @Override public String toString(){return extern;} } - String name; + String name; int mark; Sex sex; String emailAddress; diff --git a/P/Sda1/Streams/Template/src/test/java/de/hdm_stuttgart/mi/javastreams/Java8FunctionalTest.java b/P/Sda1/Streams/Template/src/test/java/de/hdm_stuttgart/mi/javastreams/Java8FunctionalTest.java index afbd1aced..61883b5a7 100644 --- a/P/Sda1/Streams/Template/src/test/java/de/hdm_stuttgart/mi/javastreams/Java8FunctionalTest.java +++ b/P/Sda1/Streams/Template/src/test/java/de/hdm_stuttgart/mi/javastreams/Java8FunctionalTest.java @@ -10,6 +10,7 @@ import java.util.stream.Collectors; import org.hamcrest.Matchers; import org.junit.Assert; +import org.junit.FixMethodOrder; import org.junit.Ignore; import org.junit.Test; @@ -17,18 +18,26 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import de.hdm_stuttgart.mi.javastreams.Student.Sex; +import org.junit.runners.MethodSorters; /** * Testing functional queries. */ @Ignore // Remove me to enable testing +@FixMethodOrder(MethodSorters.NAME_ASCENDING) public class Java8FunctionalTest { - final List<Student> roster = Student.createRoster(); + static private final List<Student> students = ImmutableList.of( + new Student("Fred", 2, Student.Sex.MALE, "fred@example.com") + ,new Student("Jane", 1, Student.Sex.FEMALE, "jane@kiv.de") + ,new Student("George", 4, Student.Sex.MALE, "george@math.edu") + ,new Student("Bob", 2, Student.Sex.MALE, "bob@uk.edu") + ,new Student("Kim", 2, Student.Sex.FEMALE, "wilde@serious.de") + ); /** * Order all male students by email and create a List<String> of their respective - * names in that order eliminating possible duplicates: + * names alphabetically ordered eliminating possible duplicates: * * "Bob", 2, Student.Sex.MALE, "bob@uk.edu" * "Fred", 2, Student.Sex.MALE, "fred@example.com" @@ -42,7 +51,7 @@ public class Java8FunctionalTest { public void allMaleDistinctNameOrderedByEmail() { final List<String> emails = - roster. + students. stream(). filter(s -> s.sex == Sex.MALE). map(Student::getName). @@ -52,7 +61,7 @@ public class Java8FunctionalTest { assertThat( emails, - Matchers.<List<String>> equalTo( + Matchers.equalTo( ImmutableList.of("Bob", "Fred", "George") ) ); @@ -66,13 +75,25 @@ public class Java8FunctionalTest { * * Expected value: 1 + 2 == 3 * - * Implementation hint: Map objects to int and provide a suitable reduce operation. - * You may want to read - * https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html#reduce + * <p>Implementation hint: Process a stream of Student instances by:</p> + * + * <ol> + * <li>Filtering students having a german email.</li> + * <li>Map objects to int.</li> + * <li>Provide a suitable reduce operation.</li> + * + * </ol> + * + * <p>You may want to read + * <a href="https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html#reduce" + * >https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html#reduce</a>.</p> */ @Test public void markSumAllStudentsMarksHavingEmail_Dot_de() { - Assert.fail("Implement me!");// TODO + Assert.assertEquals( + 3, //Expected marks sum 3 == 1 + 2 + 0 /* TODO: Start from stream students. ...*/ + ); } /** -- GitLab