├── .gitignore ├── PACKAGE_NOTES.adoc ├── README.adoc ├── fp-java-slide.pdf ├── pom.xml └── src └── main └── java ├── bytecode.sh └── com └── kodedu └── lambdas ├── Student.java ├── collect ├── CollectApp1.java ├── CollectApp2.java ├── CollectApp3.java ├── CollectApp4.java ├── CollectApp5.java └── CollectApp6.java ├── filter └── FilterApp1.java ├── flatmap ├── FlatMapApp1.java └── FlatMapApp2.java ├── function ├── FunctionApp1.java └── FunctionApp2.java ├── imperative └── App.java ├── map ├── MapApp1.java ├── MapApp2.java ├── MapApp3.java └── MapApp4.java ├── misc └── Collect.java ├── performance ├── PerfApp1.java ├── PerfApp2.java └── PerfApp3.java └── util └── Perf.java /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /.idea 3 | 4 | *.class 5 | *.iml 6 | 7 | /slide -------------------------------------------------------------------------------- /PACKAGE_NOTES.adoc: -------------------------------------------------------------------------------- 1 | = Java Stream API and Functional Programming 2 | 3 | Package descriptions can be found below: 4 | 5 | == imperative package 6 | 7 | > Differences imperative, declarative, and declarative + FP 8 | 9 | == function package 10 | 11 | > Lambda expressions & method reference 12 | 13 | == filter package 14 | 15 | > Stream API and using filters 16 | 17 | == map & flatmap package 18 | 19 | > Mapping/Transforming Stream data 20 | 21 | == collect package 22 | 23 | > Collection Stream to other objects: List, Map, etc. 24 | 25 | == performance package 26 | 27 | > Some performance notes 28 | 29 | == cleancode package 30 | 31 | > How to use clean lambda -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = Java Stream API and Functional Programming 2 | 3 | Package descriptions can be found below 4 | 5 | == Code samples 6 | 7 | Demos are separated by package name. 8 | 9 | For example `Stream#collect` samples can be found in the 'collect' package. 10 | 11 | == Slide 12 | 13 | link:fp-java-slide.pdf[Slide - FP with Java] 14 | 15 | == JDK 15 16 | 17 | Download and use JDK 15 https://jdk.java.net/15/ 18 | 19 | == Author 20 | 21 | Rahman Usta 22 | -------------------------------------------------------------------------------- /fp-java-slide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/fp-java-edu/b96662d38fbc9fe350a4c8afb60b3cf4c48ad602/fp-java-slide.pdf -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | java-fp-edu 8 | java-fp-edu 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 14 | org.apache.maven.plugins 15 | maven-compiler-plugin 16 | 3.8.1 17 | 18 | 19 | --enable-preview 20 | 21 | 15 22 | 15 23 | 24 | 25 | 26 | 27 | 28 | 29 | UTF-8 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/bytecode.sh: -------------------------------------------------------------------------------- 1 | javac com/kodedu/lambdas/function/FunctionApp1.java 2 | javap -c -p com/kodedu/lambdas/function/FunctionApp1 -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/Student.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas; 2 | 3 | public record Student(String name, String lesson, double grade) { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/collect/CollectApp1.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.collect; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | public class CollectApp1 { 8 | 9 | public static void main(String[] args) { 10 | 11 | List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 12 | 13 | // Convert numbers to List containing numbers greater than 4 14 | 15 | List list = numbers.stream() 16 | .filter(n -> n > 4) 17 | .collect(Collectors.toList()); 18 | 19 | System.out.println(list); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/collect/CollectApp2.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.collect; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Set; 6 | import java.util.stream.Collectors; 7 | 8 | public class CollectApp2 { 9 | 10 | public static void main(String[] args) { 11 | 12 | List numbers = Arrays.asList(1, 2, 1, 1, 2, 3, 4, 5, 7, 8, 10); 13 | 14 | // Convert List to Set containing numbers less than 7 15 | 16 | Set set = numbers.stream() 17 | .filter(n -> n < 7) 18 | .collect(Collectors.toSet()); 19 | 20 | System.out.println(set); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/collect/CollectApp3.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.collect; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.stream.Collectors; 7 | 8 | public class CollectApp3 { 9 | 10 | public static void main(String[] args) { 11 | 12 | List names = Arrays.asList("Hakan", null, "Burak", "Can", null, "Elif"); 13 | 14 | // Convert name list to Map containing (name -> lengthOf(name)) 15 | Map map = names.stream() 16 | .filter(n -> n != null) 17 | .collect(Collectors.toMap(name -> name, name -> name.length())); 18 | 19 | System.out.println(map); 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/collect/CollectApp4.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.collect; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.stream.Collectors; 7 | 8 | public class CollectApp4 { 9 | public static void main(String[] args) { 10 | 11 | List numbers = Arrays.asList(1, 1, 1, 1, 3, 3, 2, 2, 4, 5, 6); 12 | 13 | // Create a Map containing how many times a number repeated 14 | 15 | Map group = numbers.stream() 16 | .collect(Collectors.groupingBy(k -> k, Collectors.counting())); 17 | 18 | System.out.println(group); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/collect/CollectApp5.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.collect; 2 | 3 | 4 | import com.kodedu.lambdas.Student; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Set; 9 | import java.util.stream.Collectors; 10 | 11 | public class CollectApp5 { 12 | 13 | public static void main(String[] args) { 14 | 15 | List students = List.of( 16 | new Student("Ali", "math", 3), 17 | new Student("Ali", "cs", 4.5), 18 | new Student("Ahu", "math", 4), 19 | new Student("Ahu", "cs", 5), 20 | new Student("Ahu", "cs", 3.5), 21 | new Student("Can", "cs", 3), 22 | new Student("Can", "math", 2) 23 | ); 24 | 25 | // Student list by student name 26 | Map> map = students.stream() 27 | .collect(Collectors.groupingBy(s -> s.name())); // define key + value (list of students) 28 | 29 | // Student set by student name 30 | Map> collect2 = students.stream() 31 | // define key + value (set of students) 32 | .collect(Collectors.groupingBy(s -> s.name(), Collectors.toSet())); 33 | 34 | // Lesson set by student name 35 | Map> collect = students.stream() 36 | // defined key + value (set of lessons) 37 | .collect(Collectors.groupingBy(s -> s.name(), 38 | Collectors.mapping(s -> s.lesson(), Collectors.toSet()))); 39 | 40 | // Find average grade for each lesson by student 41 | Map> collect1 = students.stream() 42 | // defined key + value (lesson -> avg(grade) map) 43 | .collect(Collectors.groupingBy(Student::name, 44 | Collectors.groupingBy(s -> s.lesson(), 45 | Collectors.averagingDouble(s -> s.grade()) 46 | ) 47 | )); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/collect/CollectApp6.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.collect; 2 | 3 | 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | import java.nio.file.Paths; 8 | import java.util.stream.Collectors; 9 | import java.util.stream.Stream; 10 | 11 | public class CollectApp6 { 12 | 13 | public static void main(String[] args) throws IOException { 14 | 15 | // Print each folder exist in the current directory 16 | 17 | Stream stream = Files.walk(Paths.get(".")); 18 | 19 | String files = stream.filter(Files::isDirectory) 20 | .map(p -> p.toFile().toString()) 21 | .collect(Collectors.joining("\n")); 22 | 23 | System.out.println(files); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/filter/FilterApp1.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.filter; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | public class FilterApp1 { 7 | 8 | public static void main(String[] args) { 9 | List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 10 | 11 | // Print numbers greater than 4 12 | 13 | numbers.stream() 14 | .filter(n -> n > 4) 15 | .forEach(System.out::println); 16 | 17 | 18 | // Find the numbers greater than 4 and divisible by 3 19 | 20 | numbers.stream() 21 | .filter(n -> n > 4) 22 | .filter(n -> n % 3 == 0) 23 | .forEach(System.out::println); 24 | 25 | // How many operation is done in filter methods ? 26 | 27 | numbers.stream() 28 | .filter(n -> { 29 | System.out.println("Filter n> 4 :" + n); 30 | return n > 4; 31 | }) 32 | .filter(n -> { 33 | System.out.println("Filter n % 3 == 0 :" + n); 34 | return n % 3 == 0; 35 | }); 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/flatmap/FlatMapApp1.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.flatmap; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | public class FlatMapApp1 { 7 | 8 | public static void main(String[] args) { 9 | 10 | List names = Arrays.asList("Yaşar Kemal", "Sabahattin Ali", "Ahmet Ümit"); 11 | 12 | // Create 6 names from 3 author fullNames 13 | 14 | // Flat map = flatten + map 15 | 16 | names.stream() 17 | // .map(n -> Arrays.asList(n.split(" "))) 18 | .flatMap(n -> Arrays.asList(n.split(" ")).stream()) 19 | .forEach(System.out::println); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/flatmap/FlatMapApp2.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.flatmap; 2 | 3 | import java.util.List; 4 | 5 | public class FlatMapApp2 { 6 | 7 | record Person(String name, List
addressList) { 8 | } 9 | 10 | record Address(String value) { 11 | } 12 | 13 | public static void main(String[] args) { 14 | // Flat map = flatten + map 15 | 16 | List personList = List.of( 17 | new Person("Ayşe", List.of(new Address("Krakow"), new Address("İstanbul"))), 18 | new Person("Elif", List.of(new Address("İstanbul"), new Address("Ankara"))), 19 | new Person("Can", List.of(new Address("İzmir"))) 20 | ); 21 | 22 | // Print addresses of each person 23 | personList.stream() 24 | .map(p -> p.addressList()) 25 | .forEach(System.out::println); 26 | 27 | // Print each address separately 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/function/FunctionApp1.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.function; 2 | 3 | import java.util.function.Consumer; 4 | 5 | public class FunctionApp1 { 6 | 7 | public static void main(String[] args) { 8 | 9 | // Create a Consumer instance as anonymous class 10 | 11 | Consumer consumer0 = new Consumer() { 12 | @Override 13 | public void accept(String s) { 14 | System.out.println(s); 15 | } 16 | }; 17 | 18 | // Create Consumer instance with lambda expressions 19 | 20 | Consumer consumer1 = (s) -> System.out.println(s); 21 | 22 | consumer1.accept("Hello lambda expression!"); 23 | 24 | // Create instance with method reference instead of lambda 25 | 26 | Consumer consumer2 = System.out::println; 27 | 28 | consumer2.accept("Hello method reference!"); 29 | 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/function/FunctionApp2.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.function; 2 | 3 | import java.util.function.BiFunction; 4 | import java.util.function.BinaryOperator; 5 | 6 | public class FunctionApp2 { 7 | 8 | public static void main(String[] args) { 9 | 10 | // Create a BiFunction instance which sums a + b 11 | BiFunction biFunction = (a, b) -> a + b; 12 | System.out.println(biFunction.apply(3, 5)); 13 | 14 | // Simplify BiFunction usage with BinaryOperator 15 | BinaryOperator sumFunction = (a, b) -> a + b; 16 | 17 | // Pass function to higher-order function called executeSum 18 | executeSum(sumFunction, 3, 5); 19 | 20 | // Return a function from higher-order function called supplyFunction 21 | supplyFunction().apply(3, 5); 22 | 23 | } 24 | 25 | private static BinaryOperator supplyFunction() { 26 | return (a, b) -> a + b; 27 | } 28 | 29 | private static Integer executeSum(BinaryOperator function, int a, int b) { 30 | return function.apply(a, b); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/imperative/App.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.imperative; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | public class App { 7 | 8 | public static void main(String[] args) { 9 | 10 | List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 11 | 12 | // Find the number if contained in the list 13 | 14 | // Imperative 15 | System.out.println(containsNumber(numbers, 5)); 16 | 17 | // Declarative 18 | System.out.println(numbers.contains(5)); 19 | 20 | // Declarative + FP 21 | System.out.println( 22 | numbers.stream() 23 | .anyMatch(e -> e == 5) 24 | ); 25 | 26 | } 27 | 28 | private static boolean containsNumber(List numbers, int i) { 29 | boolean result = false; 30 | for (int j = 0, numbersSize = numbers.size(); j < numbersSize; j++) { 31 | Integer number = numbers.get(j); 32 | if (number == i) { 33 | result = true; 34 | break; 35 | } 36 | } 37 | return result; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/map/MapApp1.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.map; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | public class MapApp1 { 7 | public static void main(String[] args) { 8 | 9 | List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 10 | 11 | // Print the double of numbers greater than 4 12 | 13 | numbers.stream() 14 | .filter(n -> n > 4) 15 | .map(n -> n * 2) 16 | .forEach(System.out::println); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/map/MapApp2.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.map; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | public class MapApp2 { 7 | public static void main(String[] args) { 8 | 9 | List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 10 | 11 | // Print the average of numbers greater than 4 12 | 13 | System.out.println( 14 | numbers.stream() 15 | .filter(n -> n > 4) 16 | .mapToDouble(n -> n * 1.0) 17 | .average() 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/map/MapApp3.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.map; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Locale; 6 | 7 | public class MapApp3 { 8 | 9 | public static void main(String[] args) { 10 | List names = Arrays.asList("Ali", "Veli", "Can", "Elif"); 11 | 12 | // Transform names to uppercase and print 13 | names.stream() 14 | .map(n -> n.toUpperCase()) 15 | .forEach(System.out::println); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/map/MapApp4.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.map; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | public class MapApp4 { 7 | 8 | public static void main(String[] args) { 9 | List names = Arrays.asList("Sabahattin Ali", "Yaşar Kemal", "Nazım Hikmet"); 10 | 11 | // Transform String`name and surname` to Author(name,surname) 12 | 13 | record Author(String name, String surname) { 14 | } 15 | 16 | names.stream() 17 | .map(n -> n.split(" ")) 18 | .map(n -> new Author(n[0], n[1])) 19 | .forEach(System.out::println); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/misc/Collect.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.misc; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.concurrent.atomic.AtomicInteger; 6 | import java.util.stream.Stream; 7 | 8 | public class Collect { 9 | 10 | public static void main(String[] args) { 11 | // Stream.of(1, 2, 3, 4, 5).collect(ArrayList::new, ArrayList::add, ArrayList::addAll); 12 | 13 | List list = Stream.of(1, 2, 3, 4, 5) 14 | .parallel() // Comment this to see difference 15 | .collect(() -> { 16 | MyList myList = new MyList(); 17 | System.out.println("New array created " + myList); 18 | return myList; 19 | }, (arrayList, e) -> { 20 | System.out.println(arrayList + " Accumulating element :" + e); 21 | arrayList.add(e); 22 | }, (list1, list2) -> { 23 | System.out.println("Combining " + list1 + " and " + list2); 24 | list1.addAll(list2); 25 | }); 26 | 27 | System.out.println("Final list " + list); 28 | } 29 | 30 | static class MyList extends ArrayList { 31 | 32 | private static final AtomicInteger counter = new AtomicInteger(0); 33 | private volatile int value; 34 | 35 | public MyList() { 36 | value = counter.incrementAndGet(); 37 | } 38 | 39 | @Override 40 | public synchronized String toString() { 41 | return String.format("List%s{%s} - %s", value, super.toString(), Thread.currentThread().getName()); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/performance/PerfApp1.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.performance; 2 | 3 | import com.kodedu.lambdas.util.Perf; 4 | 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.IntStream; 8 | import java.util.stream.Stream; 9 | 10 | public class PerfApp1 { 11 | public static void main(String[] args) { 12 | 13 | // Difference between IntStream vs Stream ? 14 | List numbers = getNumbersBetween(1, 100000000); 15 | 16 | IntStream intStream = numbers.stream().mapToInt(e -> e); 17 | Stream stream = numbers.stream(); 18 | 19 | Perf.start(); 20 | Integer sum1 = stream.reduce(0, (a, b) -> a + b); 21 | Perf.complete("Stream"); 22 | int sum2 = intStream.sum(); 23 | Perf.complete("Intstream"); 24 | 25 | } 26 | 27 | private static List getNumbersBetween(int start, int end) { 28 | return IntStream.range(start, end).boxed().collect(Collectors.toList()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/performance/PerfApp2.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.performance; 2 | 3 | import com.kodedu.lambdas.util.Perf; 4 | 5 | import java.util.List; 6 | import java.util.concurrent.ForkJoinPool; 7 | import java.util.stream.Collectors; 8 | import java.util.stream.IntStream; 9 | 10 | public class PerfApp2 { 11 | 12 | public static void main(String[] args) { 13 | 14 | // Are parallel streams efficient ? 15 | 16 | List numbers = getNumbersBetween(1, 10000000); 17 | 18 | // Collect numbers serial vs parallel 19 | 20 | Perf.start(); 21 | numbers.stream().collect(Collectors.toList()); 22 | Perf.complete("Standard stream"); 23 | numbers.stream().parallel().collect(Collectors.toList()); 24 | Perf.complete("Parallel stream"); 25 | 26 | } 27 | 28 | private static List getNumbersBetween(int start, int end) { 29 | return IntStream.range(start, end).boxed().collect(Collectors.toList()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/performance/PerfApp3.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.performance; 2 | 3 | import com.kodedu.lambdas.util.Perf; 4 | 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.IntStream; 8 | 9 | public class PerfApp3 { 10 | 11 | public static void main(String[] args) { 12 | 13 | List numbers = getNumbersBetween(1, 100); 14 | 15 | // Are parallel streams efficient ? 16 | 17 | Perf.start(); 18 | numbers.stream().peek(PerfApp3::doSomeJob).collect(Collectors.toList()); 19 | Perf.complete("Standard stream"); 20 | numbers.stream().parallel().peek(PerfApp3::doSomeJob).collect(Collectors.toList()); 21 | Perf.complete("Parallel stream"); 22 | 23 | } 24 | 25 | private static void doSomeJob(int i) { 26 | try { 27 | Thread.sleep(10); 28 | } catch (InterruptedException e) { 29 | e.printStackTrace(); 30 | } 31 | } 32 | 33 | private static List getNumbersBetween(int start, int end) { 34 | return IntStream.range(start, end).boxed().collect(Collectors.toList()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/kodedu/lambdas/util/Perf.java: -------------------------------------------------------------------------------- 1 | package com.kodedu.lambdas.util; 2 | 3 | import java.util.function.Function; 4 | import java.util.stream.Collectors; 5 | import java.util.stream.Stream; 6 | 7 | public class Perf { 8 | 9 | private static long startTime; 10 | 11 | public static void start() { 12 | startTime = System.currentTimeMillis(); 13 | } 14 | 15 | public static long complete() { 16 | return complete(""); 17 | } 18 | 19 | public static long complete(String comment) { 20 | long currentTime = System.currentTimeMillis(); 21 | long difference = currentTime - startTime; 22 | System.out.println(String.format("%s\n\tCompleted in %s ms.", comment, difference)); 23 | startTime = System.currentTimeMillis(); 24 | return difference; 25 | } 26 | } 27 | --------------------------------------------------------------------------------