Java8 was launched in 2014, all day long calling 8 version stability, enterprises are using JDK8, the results of the 8 features are now the system of learning, sin sin ah! This series of three or four blog posts will give you a comprehensive look at the new Java 8 features.

In fact, when I usually study to see some introductory blog, always worry about writing is not complete, so I hope I can write the technology blog must be as complete as possible summed up, do see an entry level.

Lambda Quick Experience

The quickest way to get started is to watch the demo. Now there is a demand for you to pick out the red apple from the many apples

  • Apple’s class

    public class Apple { String color; int weight; Get (); // get ();

Method 1:

public static List<Apple> filterGreenAppleWithNormal(List<Apple> apples) { List<Apple> res = new ArrayList<>(); for (Apple apple : apples) { if ("red".equals(apple.getColor())) { res.add(apple); } } return res; } / / call List < > Apple normal = filterGreenAppleWithNormal (apples);

If there’s another requirement that says pick out the green apples, that way you’re going to create a new class, and then you’re just going to change “red” to “green” and nothing else, and that’s obviously not going to show up. So you can pass in the color as a parameter

Method 2:

public static List<Apple> filterGreenAppleWithArg(List<Apple> apples, String color) { List<Apple> res = new ArrayList<>(); for (Apple apple : apples) { if (color.equals(apple.getColor())) { res.add(apple); } } return res; } // call List<Apple> arg = filterGreenAppleWithArg(apples, "red");

If there is a need to select an apple of a certain weight or a certain color, what do I do? The idea above is to pile all the attributes I can think of into the parameters of the method.

public static List<Apple> filterWeightOrColorWithArg(List<Apple> apples, String color, int weight, boolean flag) { List<Apple> res = new ArrayList<>(); for (Apple apple : apples) { if (flag && color.equals(apple.getColor()) || ! flag && apple.getWeight() > weight) { res.add(apple); } } return res; } / / call List < > Apple weightOrColor = filterWeightOrColorWithArg (apples, "", 500, false);

Can I write it like that? That would solve the problem, of course, but what if I have 5 properties, 6 properties, and what does flag mean in the parameter.

If you think about it, filtering color, filtering weight, all of this is essentially filtering, it’s a behavior, it abstracts the behavior into an interface.

  • Behavior interface
public interface AppleFilter {
    boolean filter(Apple apple);

Method 3:

You first need to implement the interface to externalize the behavior

  • Filter the red apple implementation classes
public class RedFilter implements AppleFilter { @Override public boolean filter(Apple apple) { return "red".equals(apple.getColor()); }}

Go back to using

public static List<Apple> filterApples(List<Apple> apples, AppleFilter filter) { List<Apple> res = new ArrayList<>(); for (Apple apple : apples) { if (filter.filter(apple)) { res.add(apple); } } return res; } // call List<Apple> Behavior = FilterApples (Apples, new GreenFilter());

This is much more comfortable, when there is a new demand, just need to add another class, such as the need to screen out the weight of more than 200g apples, just need to create a new filter class to achieve the above interface.

public class WeightGt200Filter implements AppleFilter { @Override public boolean filter(Apple apple) { return apple.getWeight() > 200; }}

How else can you simplify your code? If you’re familiar with Java, you might think of anonymous inner classes

Method 4:

List<Apple> innerClass = filterApples(apples, new AppleFilter() { @Override public boolean filter(Apple apple) { return "green".equals(apple.getColor()); }});

Arrive this step commonly, the IDE that is quite good can begin to remind proposal

And that brings us to our focus today, lambda expressions

Method 5:

List<Apple> lambda = filterApples(apples, apple -> apple.getWeight() > 500);

Yes, it’s that simple, but FilterApples can’t be omitted, but it’s much more extensible than 1,2, and much more concise than 3,4

What is a lambda

A LAMDBA expression can be thought of as a form of concise representation of an anonymous function that can be passed around: it has no name, but it does
Parameter list, function subject, return type, and possibly a list of exceptions that can be thrown

Writing format: (parameter) -> {body}

(apple) -> {apple.getWeight() > 500; }

  • Lambda expressions can automatically infer types for arguments, and they can also display written types
  • There is no return statement because there is an implied return
  • Lambda can have multiple lines of statements

Use case:

  • () - > {}
  • () -> "java"
  • () -> {return "java"; }
  • (int a, int b) -> a * b
  • () -> {System.out.println("hello"); System.out.println("java"); }

How can I use lambda

Functional interface“Before lambda expressions can be used

A functional interface is one that defines only an abstract method, such as abstracting the behavior at first into an Applefilter interface with a single filter() method. Note that there is only one abstract method, not just one method. In general, a class that inherits the interface only needs to implement one method.

The two most common interfaces are Comparator and Runnable

In order to make it easier to distinguish between functional interfaces, the new Java API added an @FuntionalInterface annotation. This annotation simply indicates that the class is a functional interface (which is not required). If two abstract methods are declared alongside this annotation, an error will be reported

Java.util. function 4 commonly used functional interfaces

Function, Predicate, Consumer, and Predicate. There are four common functional interfaces in Java. Util. Function, Predicate, Consumer, and Predicate

These functions also depend on how the interface is declared. In this case, Predicate, for example, performs a function on an object passed in and returns a Boolean value. Is that familiar? Yes, it’s the same as screening apples

  • predicateDemo
public static List<Apple> predicateDemo(List<Apple> apples, Predicate<Apple> predicate) { List<Apple> res = new ArrayList<>(); for (Apple apple : apples) { if (predicate.test(apple)) { res.add(apple); } } return res; } // call List<Apple> predicate = predicateDemo(apples, apple-> "green".equals(apple.getColor())));

The same goes for the others, talent

  • functionDemo
public static List<Integer> functionDemo(List<Integer> nums, Function<Integer, Integer> function) { List<Integer> res = new ArrayList<>(); for (int num : nums) { res.add(function.apply(num)); } return res; } function = functionDemo(Arrays.asList(1, 8, 7, 3, 9, 2), (num) -> num * 2);
  • consumerDemo
public static void consumerDemo(List<Integer> list, Consumer<Integer> consumer) { for (int num : list) { consumer.accept(num); }} // ConsumerDemo (Arrays.asList(1, 5, 6), (num) -> System.out.println(num)); consumerDemo(Arrays.asList(1, 5, 6), System.out::println);
  • supplierDemo
public static void supplierDemo(List<Integer> nums, Supplier<String> supplier) { StringBuilder sb = new StringBuilder(); for (int num : nums) { sb.append(num).append(supplier.get()); } System.out.println(sb); } / / call supplierDemo (Arrays. AsList (1, 5, 6), () - > "Java");

Method references

Is lambda the simplest way to write lambda? No, it’s not. There’s also the simplest way to write lambda, which is to use method references

There are three main types of method references:

  • Method references to static methods
Comparator<Integer> normalComparator = (a, b) -> a.compareTo(b);
Comparator<Integer> referenceComparator = Integer::compareTo;
  • A method reference to an instance method of any type
Function<String, Integer> normalFunction = (str) -> str.length();
Function<String, Integer> referenceFunction = String::length;

BiPredicate<List<String>, String> normalPredicate = (strings, str) -> strings.contains(str);
BiPredicate<List<String>, String> referencePredicate = List::contains;
  • An instance method reference to an existing object
Apple apple = new Apple();
Supplier<Integer> normal = () -> apple.getWeight();
Supplier<Integer> reference = apple::getWeight;
  • It can also be used with constructors
Supplier<Apple> normalSupplier = () -> new Apple();
Supplier<Apple> referenceSupplier = Apple::new;


Lambda expressions in Java 8. There are a few things I haven’t covered, but I don’t think it’s necessary, such as type inference, lambda composition, throwing exceptions, unboxing, etc. Then some things are not all out, you need to junior partners to IDEA into the source code to watch.