This repository contains all the source code for the examples and quizzes in the book Java 8 in Action: Lambdas, Streams and functional-style programming.
You can purchase the book here: http://manning.com/urma/ or on Amazon
The source code for all examples can be found in the directory src/main/java/lambdasinaction
- Chapter 1: Java 8: why should you care?
- Chapter 2: Passing code with behavior parameterization
- Chapter 3: Lambda expressions
- Chapter 4: Working with Streams
- Chapter 5: Processing data with streams
- Chapter 6: Collecting data with streams
- Chapter 7: Parallel data processing and performance
- Chapter 8: Refactoring, testing, debugging
- Chapter 9: Default methods
- Chapter 10: Using Optional as a better alternative to null
- Chapter 11: CompletableFuture: composable asynchronous programming
- Chapter 12: New Date and Time API
- Chapter 13: Thinking functionally
- Chapter 14: Functional programming techniques
- Chapter 15: Blending OOP and FP: comparing Java 8 and Scala
- Chapter 16: Conclusions and "where next" for Java
- Appendix A: Miscellaneous language updates
- Appendix B: Miscellaneous library updates
- Appendix C: Performing multiple operations in parallel on a Stream
- Appendix D: Lambdas and JVM bytecode We will update the repository as we update the book. Stay tuned!
The latest binary can be found here: http://www.oracle.com/technetwork/java/javase/overview/java8-2100321.html
$ java -version
java version "1.8.0_05" Java(TM) SE Runtime Environment (build 1.8.0_05-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
You can download a preview version here: https://jdk8.java.net/
Using maven:
$ mvn compile
$ cd target/classes
$ java lambdasinaction/chap1/FilteringApples
Alternatively you can compile the files manually inside the directory src/main/java
You can also import the project in your favorite IDE: * In IntelliJ use "File->Open" menu and navigate to the folder where the project resides * In Eclipse use "File->Import->Existing Maven Projects" (also modify "Reduntant super interfaces" to report as Warnings instead of Errors * In Netbeans use "File->Open Project" menu
Table 3.2. Common functional interfaces in Java 8
package streams.world;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class JavaInActionExcercise1 {
public static void main(String[] args) {
List<Transaction> transactions = dataPopulate();
System.out.println("transactions : " + transactions);
System.out
.println("*****//Q1: Find all transactions in the year 2011 and sort them by value(small to high)***");
List<Transaction> transaction2011 = transactions.stream().filter(t -> t.getYear() == 2011)
.sorted(Comparator.comparing(Transaction::getValue)).collect(Collectors.toList());
System.out.println("transaction2011 : " + transaction2011);
System.out.println("*******************************************************************************");
System.out.println("*****//Q2: What are all the unique cities where the traders work***");
List<String> uniqueCities = transactions.stream().map(Transaction::getTrader).map(Trader::getCity).distinct()
.collect(Collectors.toList());
System.out.println("uniqueCities : " + uniqueCities);
System.out.println("*****//Q3 : Find all traders from Cambridge and sort them by name***");
List<Trader> listTraders = transactions.stream().map(Transaction::getTrader)
.filter(t -> t.getCity() == "Cambridge").sorted(Comparator.comparing(Trader::getName))
.collect(Collectors.toList());
System.out.println("listTraders : " + listTraders);
System.out.println("*****//Q4 : Return a string of all traders names sorted alphabetically***");
String sortedNames = transactions.stream().map(t -> t.getTrader().getName()).distinct().sorted().reduce("",
(n1, n2) -> n1 + " " + n2);
System.out.println("SortedNames : " + sortedNames);
System.out.println("*****//Q5 : Are any traders based in Milan***");
System.out.println(transactions.stream().map(Transaction::getTrader).anyMatch(t -> t.getCity() == "Milan"));
System.out.println(
transactions.stream().map(Transaction::getTrader).filter(t -> t.getCity() == "Milan").findAny());
System.out.println("*****//Q6 :Print all transactions values from the traders living in cambridge ***");
List<Integer> listCambridgeTrx = transactions.stream().filter(t -> t.getTrader().getCity() == "Cambridge")
.map(Transaction::getValue).collect(Collectors.toList());
System.out.println("listCambridgeTrx : " + listCambridgeTrx);
System.out.println("*****//Q7 :What's the highest value of all the transaction?***");
Optional<Integer> highestValue = transactions.stream().map(Transaction::getValue).reduce(Integer::max);
System.out.println("highestValue : " + highestValue.get());
System.out.println("*****//Q8 :Find the transaction with the smallest value***");
Optional<Transaction> smallesValue = transactions.stream()
.reduce((t1, t2) -> t1.getValue() < t2.getValue() ? t1 : t2);
System.out.println("smallesValue : " + smallesValue.get());
}
private static List<Transaction> dataPopulate() {
Trader raoul = new Trader("Raoul", "Cambridge");
Trader mario = new Trader("Mario", "Milan");
Trader alan = new Trader("Alan", "Cambridge");
Trader brian = new Trader("Brian", "Cambridge");
List<Transaction> transactions = Arrays.asList(new Transaction(brian, 2011, 300),
new Transaction(raoul, 2012, 1000), new Transaction(raoul, 2011, 400),
new Transaction(mario, 2012, 710), new Transaction(mario, 2012, 700), new Transaction(alan, 2012, 950));
return transactions;
}
}
Table 6.1. The static factory methods of the Collectors class
Factory method | Returned type | Used to | Example use |
---|---|---|---|
toList | List | Gather all the stream’s items in a List. | Example use: List dishes = menuStream.collect(toList()); |
toSet | Set | Gather all the stream’s items in a Set, eliminating duplicates. | Example use: Set dishes = menuStream.collect(toSet()); |
toCollection | Collection | Gather all the stream’s items in the collection created by the provided supplier. | Example use: Collection dishes = menuStream.collect(toCollection(), ArrayList::new); |
counting | Long | Count the number of items in the stream. | Example use: long howManyDishes = menuStream.collect(counting()); |
summingInt | Integer | Sum the values of an Integer property of the items in the stream. | Example use: int totalCalories = menuStream.collect(summingInt(Dish::getCalories)); |
averagingInt | Double | Calculate the average value of an Integer property of the items in the stream. | Example use: double avgCalories = menuStream.collect(averagingInt(Dish::getCalories)); |
summarizingInt | IntSummary-Statistics | Collect statistics regarding an Integer property of the items in the stream, such as the maximum, minimum, total, and average. | Example use: IntSummaryStatistics menuStatistics = menuStream.collect(summarizingInt(Dish::getCalories)); |
joining | String | Concatenate the strings resulting from the invocation of the toString method on each item of the stream | Example use: String shortMenu = menuStream.map(Dish::getName).collect(joining(", ")); |
maxBy | Optional | An Optional wrapping the maximal element in this stream according to the given comparator or Optional.empty() if the stream is empty. | Example use: Optional fattest = menuStream.collect(maxBy(comparingInt(Dish::getCalories))); |
minBy | Optional | An Optional wrapping the minimal element in this stream according to the given comparator or Optional.empty() if the stream is empty. | Example use: Optional lightest = menuStream.collect(minBy(comparingInt(Dish::getCalories))); |
reducing | The type produced by the reduction operation | Reduce the stream to a single value starting from an initial value used as accumulator and iteratively combining it with each item of the stream using a BinaryOperator. | Example use: int totalCalories = menuStream.collect(reducing(0, Dish::getCalories, Integer::sum)); |
collectingAndThen | The type returned by the transforming function | Wrap another collector and apply a transformation function to its result | Example use: int howManyDishes = menuStream.collect(collectingAndThen(toList(), List::size)); |
groupingBy | Map<K, List> | Group the items in the stream based on the value of one of their properties and use those values as keys in the resulting Map. | Example use: Map<Dish.Type, List> dishesByType = menuStream.collect(groupingBy(Dish::getType)); |
partitioningBy | Map<Boolean, List> | Partition the items in the stream based on the result of the application of a predicate to each of them. | Example use: Map<Boolean, List> vegetarianDishes = menuStream.collect(partitioningBy(Dish::isVegetarian)); |
Table 7.1. Stream sources and decomposability
Source | Decomposability |
---|---|
ArrayList | Excellent |
LinkedList | Poor |
IntStream.range | Excellent |
Stream.iterate | Poor |
Stream.iterate | Poor |
HashSet | Good |
TreeSet | Good |
Null