From a6d73c67e562aea4cd47dbde7ae600fbc1bf0ce2 Mon Sep 17 00:00:00 2001 From: Ken Kousen Date: Mon, 11 Dec 2023 14:23:07 -0500 Subject: [PATCH] Refactor code to use modern Java features Code has been updated across multiple files to use more modern Java features. These changes include modifying loops and if statements to use streams, replacing a ArrayList with List.of() for immutability, introducing new record PersonRecord, and updating error logging in LazyStreams. This code cleanup improves readability and makes better use of Java's capabilities. --- src/main/java/SummarizingDemo.java | 10 +++++++ src/main/java/lambdas/Person.java | 6 ++-- src/main/java/lambdas/PersonRecord.java | 23 +++++++++++++++ src/main/java/lambdas/UsePerson.java | 22 ++++++++++---- src/main/java/lazy/LazyStreams.java | 5 +--- .../refactoring/after/LoopsSortsAndIfs.java | 29 +++++-------------- 6 files changed, 59 insertions(+), 36 deletions(-) create mode 100644 src/main/java/lambdas/PersonRecord.java diff --git a/src/main/java/SummarizingDemo.java b/src/main/java/SummarizingDemo.java index afd0440..8c342e0 100644 --- a/src/main/java/SummarizingDemo.java +++ b/src/main/java/SummarizingDemo.java @@ -2,7 +2,17 @@ import java.util.stream.DoubleStream; public class SummarizingDemo { + + public static DoubleStream getLimitedRandomStream(int limit) { + return DoubleStream.generate(Math::random).limit(limit); + } + public static void main(String[] args) { + DoubleStream doubleStream = getLimitedRandomStream(10); + + doubleStream.forEach(System.out::println); + // doubleStream.forEach(System.out::println); + DoubleSummaryStatistics stats = DoubleStream.generate(Math::random) .limit(1_000_000) .summaryStatistics(); diff --git a/src/main/java/lambdas/Person.java b/src/main/java/lambdas/Person.java index 3124833..7387acd 100644 --- a/src/main/java/lambdas/Person.java +++ b/src/main/java/lambdas/Person.java @@ -30,10 +30,8 @@ public void setName(String name) { @Override public boolean equals(Object o) { if (this == o) return true; - if (!(o instanceof Person)) return false; - - Person person = (Person) o; - + // pattern matching for instanceof + if (!(o instanceof Person person)) return false; return Objects.equals(name, person.name); } diff --git a/src/main/java/lambdas/PersonRecord.java b/src/main/java/lambdas/PersonRecord.java new file mode 100644 index 0000000..7a7c008 --- /dev/null +++ b/src/main/java/lambdas/PersonRecord.java @@ -0,0 +1,23 @@ +package lambdas; + +// Records: +// - are immutable data holders +// - automatically generate equals(), hashCode(), and toString() +// - "getters" match the property names, as in "name()" +// - primary constructor is declared before the braces {} +public record PersonRecord(String name) { + + public PersonRecord(String first, String last) { + this(first + " " + last); + } + + // Copy constructor + public PersonRecord(PersonRecord other) { + this(other.name); + } + + public PersonRecord(String... names) { + this(String.join(" ", names)); + } + +} diff --git a/src/main/java/lambdas/UsePerson.java b/src/main/java/lambdas/UsePerson.java index a231dea..27b32dc 100644 --- a/src/main/java/lambdas/UsePerson.java +++ b/src/main/java/lambdas/UsePerson.java @@ -7,8 +7,9 @@ import java.util.stream.Collectors; public class UsePerson { + @SuppressWarnings("Convert2MethodRef") public static void main(String[] args) { - List names = Arrays.asList("John", "Paul", "George", "Ringo"); + List names = List.of("John", "Paul", "George", "Ringo"); // Old-style way: List beatles = new ArrayList<>(); // Shared mutable state @@ -17,14 +18,15 @@ public static void main(String[] args) { } System.out.println(beatles); + @SuppressWarnings("Convert2MethodRef") List people = names.stream() // Stream .map(name -> new Person(name)) // Stream .collect(Collectors.toList()); // Converts Stream to List System.out.println(people); people = names.stream() - .map(Person::new) // uses the Person(String) ctr - // .map(Person::new) // uses the Person(Person) ctr + .map(Person::new) // uses the Person(String) ctr + .map(Person::new) // uses the Person(Person) ctr .collect(Collectors.toList()); System.out.println(people); @@ -46,12 +48,15 @@ public static void main(String[] args) { // p1..p5 | p6..p10 | p11..p15 | p16..p20 // say you have 4 cores and run in parallel // l1 l2 l3 l4 // list - LinkedList linkedPersons = names.stream() + LinkedList linkedPersons = names.parallelStream() .map(Person::new) .collect( - () -> new LinkedList(), // Supplier + () -> new LinkedList<>(), // Supplier (list, person) -> list.add(person), // BiConsumer - (list1, list2) -> list1.addAll(list2)); // BiConsumer + (list1, list2) -> { + System.out.println("processing " + list1 + " and " + list2); + list1.addAll(list2); + }); // BiConsumer System.out.println(linkedPersons); linkedPersons = names.stream() @@ -66,5 +71,10 @@ public static void main(String[] args) { .map(Person::new) .collect(Collectors.toCollection(LinkedList::new)); System.out.println(linkedPersons); + + List records = names.stream() + .map(PersonRecord::new) + .toList(); // added in Java 16, produces immutable collections + System.out.println(records); } } diff --git a/src/main/java/lazy/LazyStreams.java b/src/main/java/lazy/LazyStreams.java index d7b8f28..c238533 100644 --- a/src/main/java/lazy/LazyStreams.java +++ b/src/main/java/lazy/LazyStreams.java @@ -1,11 +1,8 @@ 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()); @@ -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); } diff --git a/src/main/java/refactoring/after/LoopsSortsAndIfs.java b/src/main/java/refactoring/after/LoopsSortsAndIfs.java index 4b63ff1..d29482e 100644 --- a/src/main/java/refactoring/after/LoopsSortsAndIfs.java +++ b/src/main/java/refactoring/after/LoopsSortsAndIfs.java @@ -1,30 +1,15 @@ package refactoring.after; -import java.util.ArrayList; -import java.util.Collections; +import java.util.Arrays; import java.util.Comparator; -import java.util.List; public class LoopsSortsAndIfs { public static void main(String[] args) { - String[] strings = "this is an array of strings".split(" "); - - List evenLengths = new ArrayList<>(); - for (String s : strings) { - if (s.length() % 2 == 0) { - evenLengths.add(s.toUpperCase()); - } - } - - Collections.sort(evenLengths, new Comparator() { - @Override - public int compare(String s1, String s2) { - return s1.length() - s2.length(); - } - }); - - for (String s : evenLengths) { - System.out.println(s); - } + Arrays.stream("this is an array of strings".split(" ")) + .filter(s -> s.length() % 2 == 0) + .map(String::toUpperCase) + .sorted(Comparator.comparingInt(String::length) + .thenComparing(Comparator.naturalOrder())) + .forEach(System.out::println); } }