From dc0e5a439bced0c453642d0f84d291a749e5a487 Mon Sep 17 00:00:00 2001
From: Stuart Marks <stuart.marks@oracle.com>
Date: Mon, 11 Sep 2017 16:29:32 -0700
Subject: [PATCH] Various cleanups, particularly to new G Challenges.

---
 .../test/exercises/C_DefaultMethods.java      |   2 +-
 .../test/exercises/E_IntermediateStreams.java |  18 +--
 LambdaLab/test/exercises/G_Challenges.java    |  35 ++++--
 .../test/solutions/C_DefaultMethods.java      |   2 +-
 .../test/solutions/E_IntermediateStreams.java |  23 ++--
 LambdaLab/test/solutions/G_Challenges.java    | 113 +++++++++---------
 6 files changed, 101 insertions(+), 92 deletions(-)

diff --git a/LambdaLab/test/exercises/C_DefaultMethods.java b/LambdaLab/test/exercises/C_DefaultMethods.java
index f659eec..a0cb7cc 100644
--- a/LambdaLab/test/exercises/C_DefaultMethods.java
+++ b/LambdaLab/test/exercises/C_DefaultMethods.java
@@ -7,11 +7,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.stream.Collectors;
-import static org.junit.Assert.assertEquals;
 
 import org.junit.Ignore;
 import org.junit.Test;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
diff --git a/LambdaLab/test/exercises/E_IntermediateStreams.java b/LambdaLab/test/exercises/E_IntermediateStreams.java
index cc26255..b2fe843 100644
--- a/LambdaLab/test/exercises/E_IntermediateStreams.java
+++ b/LambdaLab/test/exercises/E_IntermediateStreams.java
@@ -12,6 +12,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Objects;
 import java.util.Random;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
@@ -19,12 +20,10 @@ import java.util.stream.LongStream;
 import java.util.stream.Stream;
 
 import org.junit.After;
-import static org.junit.Assert.assertEquals;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 /**
@@ -214,7 +213,7 @@ public class E_IntermediateStreams {
     // </editor-fold>
 
     /**
-     * Create a list containing all the super classes of ArrayList.
+     * Create a list containing ArrayList.class and all its super classes.
      */
     @Test @Ignore
     public void e8_selectTheSuperClassesOfArrayList() {
@@ -223,8 +222,8 @@ public class E_IntermediateStreams {
         List<String> result = null; // TODO
 
         assertEquals(
-                Arrays.asList(ArrayList.class, AbstractList.class, AbstractCollection.class, Object.class),
-                result);
+            List.of(ArrayList.class, AbstractList.class, AbstractCollection.class, Object.class),
+            result);
     }
     // Hint:
     // <editor-fold defaultstate="collapsed">
@@ -245,9 +244,10 @@ public class E_IntermediateStreams {
         Stream<String> stream = Stream.iterate(
                 "",
                 (String s) -> {
-                final int nextInt = rand.nextInt(10);
-                return (nextInt == 0 && !s.isEmpty()) ? s.substring(0, s.length() - 1) :
-                       (nextInt == 8 || nextInt == 9) ? s + "+" : s;
+                    final int nextInt = rand.nextInt(10);
+                    return (nextInt == 0 && !s.isEmpty()) ? s.substring(0, s.length() - 1) :
+                           (nextInt == 8 || nextInt == 9) ? s + "+"
+                                                          : s;
                 }).limit(100);
 
         long count = 0L; // TODO
diff --git a/LambdaLab/test/exercises/G_Challenges.java b/LambdaLab/test/exercises/G_Challenges.java
index a7f0068..f22c37a 100644
--- a/LambdaLab/test/exercises/G_Challenges.java
+++ b/LambdaLab/test/exercises/G_Challenges.java
@@ -12,6 +12,7 @@ import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.OptionalInt;
 import java.util.RandomAccess;
 import java.util.Set;
@@ -24,7 +25,6 @@ import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
-import org.junit.Ignore;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -321,18 +321,20 @@ public class G_Challenges {
         Class<?> origin = ArrayList.class;
         Map<Boolean, Set<Class<?>>> result = null; // TODO
 
-        assertEquals(result.get(false), Set.of(ArrayList.class, Object.class));
-        assertEquals(result.get(true), Set.of(List.class, RandomAccess.class, Cloneable.class, Serializable.class, Collection.class));
+        assertEquals(Map.of(false, Set.of(ArrayList.class, Object.class),
+                            true,  Set.of(List.class, RandomAccess.class, Cloneable.class,
+                                          Serializable.class, Collection.class)),
+                     result);
     }
     // Hint:
     // <editor-fold defaultstate="collapsed">
     // The beginning of this challenge begins with the same kind of pattern
     // as the E8 intermediate exercise.
     // The interfaces are returned in an array, so one can put them in a stream
-    // using Stream.of(). To add the class to that stream, you can also
+    // using Arrays.stream(). To add the class to that stream, you can also
     // use Stream.of() and flatMap the result to have the final stream.
     // Writing the filter step is just a matter of creating the right predicate.
-    // Then the partionningBy collector will build the map.
+    // Then the partioningBy collector will build the map.
     // </editor-fold>
 
     /**
@@ -348,17 +350,26 @@ public class G_Challenges {
         List<Class<?>> origin = List.of(ArrayList.class, HashSet.class, LinkedHashSet.class);
         Map<Class<?>, Map<Boolean, Set<Class<?>>>> result = null; // TODO
 
-        assertEquals(result.get(ArrayList.class).get(false), Set.of(ArrayList.class, Object.class));
-        assertEquals(result.get(ArrayList.class).get(true), Set.of(List.class, RandomAccess.class, Cloneable.class, Serializable.class, Collection.class));
-        assertEquals(result.get(HashSet.class).get(false), Set.of(HashSet.class, Object.class));
-        assertEquals(result.get(HashSet.class).get(true), Set.of(Set.class, Cloneable.class, Serializable.class, Collection.class));
-        assertEquals(result.get(LinkedHashSet.class).get(false), Set.of(LinkedHashSet.class, HashSet.class, Object.class));
-        assertEquals(result.get(LinkedHashSet.class).get(true), Set.of(Set.class, Cloneable.class, Serializable.class, Collection.class));
+        assertEquals(
+            Map.of(
+                ArrayList.class,
+                    Map.of(false, Set.of(ArrayList.class, Object.class),
+                           true,  Set.of(List.class, RandomAccess.class, Cloneable.class,
+                                         Serializable.class, Collection.class)),
+                HashSet.class,
+                    Map.of(false, Set.of(HashSet.class, Object.class),
+                           true,  Set.of(Set.class, Cloneable.class,
+                                         Serializable.class, Collection.class)),
+                LinkedHashSet.class,
+                    Map.of(false, Set.of(LinkedHashSet.class, HashSet.class, Object.class),
+                           true,  Set.of(Set.class, Cloneable.class,
+                                         Serializable.class, Collection.class))),
+            result);
     }
     // Hint:
     // <editor-fold defaultstate="collapsed">
     // The trick here is to write the whole processing of the previous
-    // C81 challenge as a single collector. Once this is done, just pass
+    // G8 challenge as a single collector. Once this is done, just pass
     // this collector as the downstream collector of a groupingBy.
     // A filtering collector and a flatMapping collector have been added
     // to JDK9.
diff --git a/LambdaLab/test/solutions/C_DefaultMethods.java b/LambdaLab/test/solutions/C_DefaultMethods.java
index 74120ba..77e6781 100644
--- a/LambdaLab/test/solutions/C_DefaultMethods.java
+++ b/LambdaLab/test/solutions/C_DefaultMethods.java
@@ -7,11 +7,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.stream.Collectors;
-import static org.junit.Assert.assertEquals;
 
 import org.junit.Ignore;
 import org.junit.Test;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
diff --git a/LambdaLab/test/solutions/E_IntermediateStreams.java b/LambdaLab/test/solutions/E_IntermediateStreams.java
index e03d561..1253578 100644
--- a/LambdaLab/test/solutions/E_IntermediateStreams.java
+++ b/LambdaLab/test/solutions/E_IntermediateStreams.java
@@ -12,6 +12,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Objects;
 import java.util.Random;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
@@ -19,12 +20,10 @@ import java.util.stream.LongStream;
 import java.util.stream.Stream;
 
 import org.junit.After;
-import static org.junit.Assert.assertEquals;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 /**
@@ -268,7 +267,7 @@ public class E_IntermediateStreams {
     // </editor-fold>
 
     /**
-     * Create a list containing all the super classes of ArrayList.
+     * Create a list containing ArrayList.class and all its super classes.
      */
     @Test
     public void e8_selectTheSuperClassesOfArrayList() {
@@ -276,13 +275,14 @@ public class E_IntermediateStreams {
 
         //TODO//List<String> result = null;
         //BEGINREMOVE
-        Stream<Class<?>> stream = Stream.<Class<?>>iterate(origin, clazz -> clazz.getSuperclass());
-        List<Class<?>> result = stream.takeWhile(clazz -> clazz != null).collect(Collectors.toList());
+        List<Class<?>> result = Stream.<Class<?>>iterate(origin, Class::getSuperclass)
+                                      .takeWhile(Objects::nonNull)
+                                      .collect(Collectors.toList());
         //ENDREMOVE
 
         assertEquals(
-                Arrays.asList(ArrayList.class, AbstractList.class, AbstractCollection.class, Object.class),
-                result);
+            List.of(ArrayList.class, AbstractList.class, AbstractCollection.class, Object.class),
+            result);
     }
     // Hint:
     // <editor-fold defaultstate="collapsed">
@@ -303,9 +303,10 @@ public class E_IntermediateStreams {
         Stream<String> stream = Stream.iterate(
                 "",
                 (String s) -> {
-                final int nextInt = rand.nextInt(10);
-                return (nextInt == 0 && !s.isEmpty()) ? s.substring(0, s.length() - 1) :
-                       (nextInt == 8 || nextInt == 9) ? s + "+" : s;
+                    final int nextInt = rand.nextInt(10);
+                    return (nextInt == 0 && !s.isEmpty()) ? s.substring(0, s.length() - 1) :
+                           (nextInt == 8 || nextInt == 9) ? s + "+"
+                                                          : s;
                 }).limit(100);
 
         //TODO//long count = 0L;
diff --git a/LambdaLab/test/solutions/G_Challenges.java b/LambdaLab/test/solutions/G_Challenges.java
index 4408cc1..08f7ced 100644
--- a/LambdaLab/test/solutions/G_Challenges.java
+++ b/LambdaLab/test/solutions/G_Challenges.java
@@ -12,6 +12,7 @@ import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.OptionalInt;
 import java.util.RandomAccess;
 import java.util.Set;
@@ -24,7 +25,6 @@ import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
-import org.junit.Ignore;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -433,31 +433,34 @@ public class G_Challenges {
         Class<?> origin = ArrayList.class;
         //TODO//Map<Boolean, Set<Class<?>>> result = null;
         //BEGINREMOVE
-        Stream<Class<?>> stream = Stream.<Class<?>>iterate(ArrayList.class, c -> c.getSuperclass()).takeWhile(c -> c != null);
         Stream<Class<?>> classesAndInterfaces =
-            stream.map(c -> Stream.of(Stream.of(c), Stream.of(c.getInterfaces())))
-                  .flatMap(Function.identity())
+            Stream.<Class<?>>iterate(origin, Class::getSuperclass)
+                  .takeWhile(Objects::nonNull)
+                  .flatMap(c -> Stream.of(Stream.of(c), Arrays.stream(c.getInterfaces())))
                   .flatMap(Function.identity());
-        Predicate<Class<?>> isAbstract = c -> Modifier.isAbstract(c.getModifiers());
+
+        Predicate<Class<?>> isConcrete = c -> ! Modifier.isAbstract(c.getModifiers());
         Predicate<Class<?>> isInterface = Class::isInterface;
-        Stream<Class<?>> interfacesAndConcreteClasses =
-            classesAndInterfaces.filter(isInterface.or(isAbstract.and(isInterface.negate()).negate()));
+
         Map<Boolean, Set<Class<?>>> result =
-            interfacesAndConcreteClasses.collect(Collectors.partitioningBy(isInterface, Collectors.toSet()));
+            classesAndInterfaces.filter(isInterface.or(isConcrete))
+                                .collect(Collectors.partitioningBy(isInterface, Collectors.toSet()));
         //ENDREMOVE
 
-        assertEquals(result.get(false), Set.of(ArrayList.class, Object.class));
-        assertEquals(result.get(true), Set.of(List.class, RandomAccess.class, Cloneable.class, Serializable.class, Collection.class));
+        assertEquals(Map.of(false, Set.of(ArrayList.class, Object.class),
+                            true,  Set.of(List.class, RandomAccess.class, Cloneable.class,
+                                          Serializable.class, Collection.class)),
+                     result);
     }
     // Hint:
     // <editor-fold defaultstate="collapsed">
     // The beginning of this challenge begins with the same kind of pattern
     // as the E8 intermediate exercise.
     // The interfaces are returned in an array, so one can put them in a stream
-    // using Stream.of(). To add the class to that stream, you can also
+    // using Arrays.stream(). To add the class to that stream, you can also
     // use Stream.of() and flatMap the result to have the final stream.
     // Writing the filter step is just a matter of creating the right predicate.
-    // Then the partionningBy collector will build the map.
+    // Then the partioningBy collector will build the map.
     // </editor-fold>
 
     /**
@@ -474,70 +477,64 @@ public class G_Challenges {
         //TODO//Map<Class<?>, Map<Boolean, Set<Class<?>>>> result = null;
         //BEGINREMOVE
         Function<Class<?>, Stream<Class<?>>> superClasses =
-                clazz -> Stream.<Class<?>>iterate(clazz, c -> c.getSuperclass()).takeWhile(c -> c != null);
+                clazz -> Stream.<Class<?>>iterate(clazz, Class::getSuperclass)
+                               .takeWhile(Objects::nonNull);
+
         Function<Stream<? extends Class<?>>, Stream<? extends Class<?>>> classAndInterfaces =
-                stream -> stream.map(clazz -> Stream.of(Stream.of(clazz), Stream.of(clazz.getInterfaces())))
-                                .flatMap(Function.identity())
+                stream -> stream.flatMap(clazz -> Stream.of(Stream.of(clazz), Arrays.stream(clazz.getInterfaces())))
                                 .flatMap(Function.identity());
 
         Function<Class<?>, Stream<? extends Class<?>>> superClassesAndInterfaces = superClasses.andThen(classAndInterfaces);
 
-        Predicate<Class<?>> isAbstract = c -> Modifier.isAbstract(c.getModifiers());
+        Predicate<Class<?>> isConcrete = c -> ! Modifier.isAbstract(c.getModifiers());
         Predicate<Class<?>> isInterface = Class::isInterface;
-        Predicate<Class<?>> isInterfaceOrConcreteClass = isInterface.or(isAbstract.and(isInterface.negate()).negate());
-
-        List<Class<?>> classes = List.of(ArrayList.class);
-
-        // 1) write the previous processing as a stream pattern
-        Map<Boolean, Set<Class<?>>> collect =
-        classes.stream()
-                .flatMap(superClassesAndInterfaces)
-                .filter(isInterfaceOrConcreteClass)
-                .collect(
-                        Collectors.partitioningBy(
-                                isInterface,
-                                Collectors.toSet()
-                        )
-                );
+        Predicate<Class<?>> isInterfaceOrConcreteClass = isInterface.or(isConcrete);
+
+        // 1) To understand the algorithm, write out the previous processing as a stream pattern.
+        //    This isn't used directly, but will be converted to a collector below.
+        Map<Boolean, Set<Class<?>>> unusedResult =
+            origin.stream()
+                  .flatMap(superClassesAndInterfaces)
+                  .filter(isInterfaceOrConcreteClass)
+                  .collect(Collectors.partitioningBy(isInterface,
+                                                     Collectors.toSet()));
 
         // 2) Convert the processing to a collector
         Collector<Class<?>, ?, Map<Boolean, Set<Class<?>>>> collector =
-                Collectors.flatMapping(
-                        superClassesAndInterfaces,
-                        Collectors.filtering(
-                                isInterfaceOrConcreteClass,
-                                Collectors.partitioningBy(
-                                    isInterface,
-                                    Collectors.toSet()
-                                )
-                        )
-                );
-
-        // 3) use it at a downstream collector
-        Map<Class<?>, Map<Boolean, Set<Class<?>>>> result =
-        origin.stream()
-                .collect(
-                        Collectors.groupingBy(
-                                Function.identity(),
-                                collector
-                        )
-                );
+            Collectors.flatMapping(superClassesAndInterfaces,
+                                   Collectors.filtering(isInterfaceOrConcreteClass,
+                                                        Collectors.partitioningBy(isInterface,
+                                                                                  Collectors.toSet())));
 
+        // 3) use it as a downstream collector
+        Map<Class<?>, Map<Boolean, Set<Class<?>>>> result =
+            origin.stream()
+                  .collect(Collectors.groupingBy(Function.identity(),
+                                                 collector));
 
         System.out.println("result = " + result);
         //ENDREMOVE
 
-        assertEquals(result.get(ArrayList.class).get(false), Set.of(ArrayList.class, Object.class));
-        assertEquals(result.get(ArrayList.class).get(true), Set.of(List.class, RandomAccess.class, Cloneable.class, Serializable.class, Collection.class));
-        assertEquals(result.get(HashSet.class).get(false), Set.of(HashSet.class, Object.class));
-        assertEquals(result.get(HashSet.class).get(true), Set.of(Set.class, Cloneable.class, Serializable.class, Collection.class));
-        assertEquals(result.get(LinkedHashSet.class).get(false), Set.of(LinkedHashSet.class, HashSet.class, Object.class));
-        assertEquals(result.get(LinkedHashSet.class).get(true), Set.of(Set.class, Cloneable.class, Serializable.class, Collection.class));
+        assertEquals(
+            Map.of(
+                ArrayList.class,
+                    Map.of(false, Set.of(ArrayList.class, Object.class),
+                           true,  Set.of(List.class, RandomAccess.class, Cloneable.class,
+                                         Serializable.class, Collection.class)),
+                HashSet.class,
+                    Map.of(false, Set.of(HashSet.class, Object.class),
+                           true,  Set.of(Set.class, Cloneable.class,
+                                         Serializable.class, Collection.class)),
+                LinkedHashSet.class,
+                    Map.of(false, Set.of(LinkedHashSet.class, HashSet.class, Object.class),
+                           true,  Set.of(Set.class, Cloneable.class,
+                                         Serializable.class, Collection.class))),
+            result);
     }
     // Hint:
     // <editor-fold defaultstate="collapsed">
     // The trick here is to write the whole processing of the previous
-    // C81 challenge as a single collector. Once this is done, just pass
+    // G8 challenge as a single collector. Once this is done, just pass
     // this collector as the downstream collector of a groupingBy.
     // A filtering collector and a flatMapping collector have been added
     // to JDK9.
-- 
GitLab