Skip to content

Commit

Permalink
Refactor code and Enhance tests in StringExercises class
Browse files Browse the repository at this point in the history
Code in the `StringExercises` and `LazyStreams` class was refactored for easier readability. Several import statements were consolidated using import java.util.*. In addition, Logger and Predicate libraries were imported and utilized to improve test outputs and function compositions. This makes the code more elegant and enhances debugging capabilities.

The tests in `StringExercises` now cover more scenarios like null check in 'demoCollectors' method and applying the 'functionThenConsumer'. These changes increase the comprehensiveness and the accuracy of the tests.

LazyStreams also underwent a minor structural reordering in 'printNumbers' method to simplify code. In total, these changes improve code ease-of-use, readability, and testing verification.
  • Loading branch information
kousen committed Oct 4, 2023
1 parent 05676d7 commit cfa5603
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 18 deletions.
9 changes: 3 additions & 6 deletions src/main/java/lazy/LazyStreams.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
package lazy;

import java.util.logging.Logger;
import java.util.stream.IntStream;

public class LazyStreams {
private static final Logger logger = Logger.getLogger(LazyStreams.class.getName());

public static int multByTwo(int n) {
System.out.printf("Inside multByTwo with arg %d on thread %s%n",
n, Thread.currentThread().getName());
return n * 2;
}

public static boolean modByThree(int n) {
System.out.printf("Inside modByThree with arg %d on thread %s%n", n,
Thread.currentThread().getName());
System.out.printf("Inside modByThree with arg %d on thread %s%n",
n, Thread.currentThread().getName());
return n % 3 == 0;
}

Expand All @@ -30,8 +27,8 @@ public static void main(String[] args) {
// Demonstrate laziness using print statements
firstEvenDoubleDivBy3 = IntStream.rangeClosed(100, 2_000_000)
// .parallel()
.filter(LazyStreams::modByThree)
.map(LazyStreams::multByTwo)
.filter(LazyStreams::modByThree)
.findFirst().orElse(0);
System.out.printf("First even divisible by 3 is %d%n", firstEvenDoubleDivBy3);
}
Expand Down
66 changes: 54 additions & 12 deletions src/test/java/streams/StringExercises.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@

import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertThat;

public class StringExercises {
private final List<String> strings =
Arrays.asList("this", "is", "a", "list", "of", "strings");

@SuppressWarnings("Convert2Lambda")
@Test
public void stringLengthSort_InnerClass() { // Java 5, 6, 7
strings.sort(new Comparator<String>() {
strings.sort(new Comparator<>() {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
Expand All @@ -24,6 +27,7 @@ public int compare(String s1, String s2) {
System.out.println(strings);
}

@SuppressWarnings("ComparatorCombinators")
@Test
public void stringLengthSort_lambda() {
// Use lambda for the Comparator (reverse sort)
Expand All @@ -42,40 +46,78 @@ private int compareStrings(String s1, String s2) {
return s1.length() - s2.length();
}

@SuppressWarnings("Convert2MethodRef")
@Test // Use a lambda that calls 'compareStrings' directly
public void stringLengthSort_methodCall() {

List<String> sorted = strings.stream()
.sorted((s1, s2) -> compareStrings(s1, s2))
.collect(Collectors.toList());
System.out.println(sorted);
}

@Test // Use a method ref to 'compareStrings'
public void stringLengthSort_methodRef() {

List<String> sorted = strings.stream()
.sorted(this::compareStrings)
.collect(Collectors.toList());
System.out.println(sorted);
}

@Test // Use Comparator.comparingInt
public void stringLengthSort_comparingInt() {

List<String> sorted = strings.stream()
.sorted(Comparator.comparingInt(String::length)
.thenComparing(Comparator.naturalOrder()))
.collect(Collectors.toList());
System.out.println(sorted);
}

@Test
public void demoCollectors() {
// Get only strings of even length
// Add them to a LinkedList
LinkedList<String> evens = strings.stream()
.filter(s -> s.length() % 2 == 0)
.collect(Collectors.toCollection(LinkedList::new));
System.out.println(evens);
assertThat(evens).isExactlyInstanceOf(LinkedList.class);

// Add the strings to a map of string to length
Map<String, Integer> map = strings.stream()
// .collect(Collectors.toMap(s -> s, String::length));
.collect(Collectors.toMap(Function.identity(), String::length));
System.out.println(map);

// Filter out nulls, then print even-length strings
List<String> stringsWithNulls = Arrays.asList("this", null, "is", null,
"a", null, "list", null, "of", null, "strings");
List<String> evenLengths = stringsWithNulls.stream()
//.filter(s -> s != null && s.length() % 2 == 0) // short-circuiting logical AND
//.filter(s -> s != null)
.filter(Objects::nonNull)
.filter(s -> s.length() % 2 == 0)
.collect(Collectors.toList());
System.out.println(evenLengths);

Logger logger = Logger.getLogger("demoCollectors");

// Function composition
Predicate<String> nonNull = Objects::nonNull;
Predicate<String> evenLength = s -> s.length() % 2 == 0;

Consumer<String> log = logger::info;
Consumer<Object> print = System.out::println;

// Combine the two predicates and use the result to print non-null, even-length strings
stringsWithNulls.stream()
.filter(nonNull.and(evenLength)) // function composition
.forEach(log.andThen(print)); // function composition

// f: A -> B, g: B -> C, (g.f)(x) = g(f(x)), A -> C
strings.forEach(s -> functionThenConsumer(String::length, print, s));
}

// generated by GitHub Copilot
private <A, B, C> Function<A, C> compose(Function<A, B> f, Function<B, C> g) {
return x -> g.apply(f.apply(x));
private <T,U> void functionThenConsumer(Function<T,U> f, Consumer<U> c, T t) {
c.accept(f.apply(t));
}

}

0 comments on commit cfa5603

Please sign in to comment.