Integration Demo 1 - Basics
public static void main(String[] args) { List<Dish> menu = new ArrayList<>(); List<Dish> dishes = menu.stream() // convert into Stream Object .filter(d -> d.getCalories() > 300) // == if statement .limit(3) // == limit the result size .skip(2) // == abandon the first 2 result .sorted(...) // sort by asc, can pass a Comparator as well .collect(Collectors.toList()); // convert back to list }
Integration Demo 2 - Map
Map function is to implement such and such a method upon each element in collection.List<Dish> menu = new ArrayList<>(); List<Integer> dishNameLengths = menu.stream() .map(Dish::getName) // retrive each element's name .map(String::length) // further retrive each name's length .distinct() .collect(Collectors.toList());
flatMap function is to implement such and such a method on each element, then combine multiple Stream into one Stream.
List<String> words = new ArrayList<>(); List<String> uniqueCharacters = words.stream() .map(w -> w.split("")) // convert into multple Stream<String[]> .flatMap(Arrays::stream) // combine into one Stream<String> .distinct() .collect(Collectors.toList());
Integration Demo 3 - Match & Find
Match & Find is implemented in Java 7 using regular expression, In Java 8 , it gives you more flexbile way to do it . In Stream API, the following functions are provided :allMatch、anyMatch、noneMatch、findFirst and findAny
public static void main(String[] args) { List<Dish> menu = new ArrayList<>(); // match if (menu.stream().anyMatch(Dish::isVegetarian)) { // at least one matched System.out.println("matched"); } if (menu.stream().allMatch(d -> d.getCalories() < 1000)) { // all matched System.out.println("matched"); }
if (menu.stream().noneMatch(d -> d.getCalories() >= 1000)) { // none matched System.out.println("matched"); } }
Optional<T> interface is the return type of Java 8 Match & Find, Becuase If none is found , It may throw NullPointerException,So this Interface is invented to avoid that . It has 4 inherited methods
- isPresent() , if something is returned, return true, if nothing is returned, return false.
- ifPresent(Consumer<T> block), if somehting is returned, then run a code block.
- T get(), if something is retured, then get the returned value, else throw NoSuchElementExceptio
- T orElse(T other), if nothing is returned, it can set a default value and return back.
Optional<Dish> dish = menu.stream() .filter(Dish::isVegetarian) .findAny(); menu.stream().filter(Dish::isVegetarian)
.findAny()
.ifPresent(d -> System.out.println(d.getName())); // if something is returned,
then print List<Integer> someNumbers = Arrays.asList(1, 2, 3, 4, 5); Optional<Integer> firstSquareDivisibleByThree = someNumbers.stream() .map(x -> x * x) // inner product of each element .filter(x -> x % 3 == 0) .findFirst(); // 9
Integration Demo 4 - Reduce
What's reduce? well , you may hear of mapreduce, reducing is a process of summarizing the result or final math computation.public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); int sum = numbers.stream().reduce(0, (a, b) -> a + b); // get the sum int product = numbers.stream().reduce(1, (a, b) -> a * b); // get the product Optional<Integer> max = numbers.stream().reduce(Integer::max); // get the max Optional<Integer> min = numbers.stream().reduce(Integer::min); // get the min List<Dish> menu = new ArrayList<>(); int count = menu.stream() .map(d -> 1) .reduce(0, (a, b) -> a + b); // count the total , using mapreduce }
Integration Demo 6 - Number Steam
Stream is not always the boss , sometimes , when it convert into some primitive types to facilitate some computations , it may face autoboxing and unboxing issues, thus , some his little brothers are invented. IntStream、DoubleStream & LongStream
public static void main(String[] args) {
List<Dish> menu = new ArrayList<>(); int calories = menu.stream() .mapToInt(Dish::getCalories) // convert Stream into IntStream .sum(); IntStream intStream = menu.stream().mapToInt(Dish::getCalories); Stream<Integer> stream = intStream.boxed(); // upgrade IntStream back to Stream OptionalInt maxCalories = menu.stream() .mapToInt(Dish::getCalories) .max(); // get the max int max = maxCalories.orElse(1); // if no max value, then return 1 as default IntStream evenNumbers = IntStream.rangeClosed(1, 100) // do between 1~100 .filter(n -> n % 2 == 0); System.out.println(evenNumbers.count()); Stream<int[]> pythagoreanTriples = IntStream.rangeClosed(1, 100)
.boxed() // upgrade to Stream
.flatMap(a -> IntStream.rangeClosed(a, 100) .filter(b -> Math.sqrt(a*a + b*b) % 1 == 0) .mapToObj(b -> new int[]{a, b, (int)Math.sqrt(a * a + b * b)}));
// convert primitive type into Object }
Integration Demo 7 - Create Steam
Stream Creation as we know is from collection. Yes, That's the commonest way. However, There're still some other ways to create a Stream which are not commonly used.public static void main(String[] args) { // created from values
Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action"); Stream<String> emptyStream = Stream.empty(); // create a empty Stream int[] numbers = {2, 3, 5, 7, 11, 13}; int sum = Arrays.stream(numbers).sum(); // created from array
// created from a file
Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset()); // created from function iterate()
Stream.iterate(0, n -> n + 2).limit(10).forEach(System.out::println);
// created from function generate() Stream.generate(Math::random).limit(5).forEach(System.out::println); IntStream twos = IntStream.generate(new IntSupplier() { public int getAsInt() { return 2; }}); // created from code block }
Well , That's all about the guide of Stream. In Next article , I will demostrate how to make use of different Streams to encapsulate a powerful application.
No comments:
Post a Comment