New features of Java8: Lambda expressions, functional interfaces, Stream API (notes)

1. Lambda expression

Lambda is a new feature of Java 8. Using Lambda can replace the implementation of an interface (function interface) with only one abstract method, similar to an anonymous inner class.

1.1. Lambda syntax format

()-> {
    
    }
  • (): Used to describe the parameter list.
  • {}: Used to describe the method body and execution statement. It can be omitted when there is only one execution statement or only return value.
  • -> :Lambda operator

1.2. Lambda basic syntax example
to create multiple interfaces

public interface LambdaInterface {
    
    
    int test1();
}

@FunctionalInterface
public interface LambdaInterface1 {
    
    
    int test2(int a);
}

@FunctionalInterface
public interface LambdaInterface2 {
    
    
   int test3(int a,int b);
}

@FunctionalInterface
public interface LambdaInterface3 {
    
    
    void test4();
}

@FunctionalInterface
public interface LambdaInterface4 {
    
    
  void test5(int a);
}


@FunctionalInterface
public interface LambdaInterface5 {
    
    
   void test6(int a,int b);
}

Test class

public class LambdaTest {
    
    
    public static void main(String[] args) {
    
    
        /**
         * 无参数,有返回值
         */

        //LambdaInterface test = () ->{return 200;};
        LambdaInterface test = () -> 200;
        int i2 = test.test1();
        System.out.println(i2);
        /**
         * 有单个参数,有返回值
         */
        //LambdaInterface1 test2 = (int a) ->{return a;};
        LambdaInterface1 test2 = a -> a;
        int i3 = test2.test2(200);
        System.out.println(i3);
        /**
         * 有多个参数,有返回值
         */
        //LambdaInterface2 test3 =(int a ,int b) -> {return a-b;};
        LambdaInterface2 test3 =(a,b) -> a-b;
        int i = test3.test3(20, 1);
        System.out.println(i);
        /**
         * 有参数,无返回值
         */
       // LambdaInterface4 test4 = a -> {System.out.println(a);};
        LambdaInterface4 test4 = a -> System.out.println(a);
        test4.test5(12);
        /**
         * 有多个参数,无返回值
         */
        //LambdaInterface5 test5 = (a, b) ->{System.out.println("a="+a+"  b="+b);};
        LambdaInterface5 test5 = (a, b) -> System.out.println(a+b);
        test5.test6(12,24);
        /**
         * 无参数,无返回值
         */
        LambdaInterface3 test6 = () -> System.out.println("无参数,无返回值!");
        test6.test4();
    }

}

Output result
Insert image description here
1.3, Lambda method reference

Method reference: If the content in the Lambda body has a method that has been implemented, we can use "method reference (which can be understood as method reference is another form of expression of Lambda expression). There are three main syntax formats: Object::
instantiation
method Name
Class::Static method name
Class::Instance method name
Note: 1. The parameter list and return value type of the calling method in the Lambda body must be consistent with the function list and return value type of the abstract method in the functional interface! 2
. If the first parameter in the Lambda parameter list is the caller of the instance method, and the second parameter is the parameter of the instance method, you can use ClassName::method

  //对象::实例方法名
    @Test
    public  void test1(){
    
    
        //Consumer<String> con1 =(x) -> System.out.println(x);
        Consumer<String> con = System.out::println;
        con.accept("adcdef");
    }
    //类::静态方法名
    @Test
    public void test2(){
    
    
      //Comparator<Integer> com = (x ,y) ->Integer.compare(x,y);

      Comparator<Integer> com1 = Integer::compare;
    }
    //类::实例方法名
    @Test
    public void test3(){
    
    
        //BiPredicate<String,String> bp =(x,y) -> x.equals(y);
        BiPredicate<String,String> bp =String::equals;
    }
    //数组引用
    @Test
    public void test4(){
    
    
        //Function<Integer,String[]> fun =(x) ->new String[x];
        Function<Integer,String[]> fun = String[]::new;
        String[] strs = fun.apply(10);
        System.out.println(strs.length);
    }

}

Output result
Insert image description here
1.4, method reference (constructor)
creates entity class

public class Person {
    
    
    public String name;
    public int age;

    public Person(){
    
    
        System.out.println("这是无参构造方法");
    }
    public Person(String name,int age){
    
    
        System.out.println("这里是有参构造");
        this.name=name;
        this.age=age;
    }

    @Override
    public String toString() {
    
    
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Create interface

interface LambdaInterfaceTest{
    
    
    Person getPerson();
}
interface LambdaInterfaceTest1{
    
    
    Person getPerson(String name,int age);
}

Test class


public class LambdaTest2 {
    
    
    public static void main(String[] args) {
    
    
        LambdaInterfaceTest test = ()-> new Person();
        test.getPerson();
        //构造方法的引用
        LambdaInterfaceTest test1 = Person::new;
        test1.getPerson();
        LambdaInterfaceTest1 test11 =Person::new;
        test11.getPerson("lzf",12);

    }
}

Output results
Insert image description here

2. Functional interface

1. The prerequisite for using Lambda expressions is that the interface must be a functional interface.
2. A functional interface (FunctionalInterface) is an interface that has one and only one abstract method, but can have multiple non-abstract methods.
3. Functional interfaces can be implicitly converted into lambda expressions.
4. Lambda expressions and method references (actually can also be considered Lambda expressions)
5. Use the annotation @FunctionalInterface

Four built-in core function interfaces

public class Lambda5 {
    
    
    //Supplier<T>
    @Test
    public void test1(){
    
    
        List<Integer> numList = getNumList(10, () -> (int) (Math.random() * 100));
        for (Integer n:numList) {
    
    
            System.out.print(n+" ");
        }
    }
    //需求:产生指定个数的整数,并放入集合中
    public List<Integer> getNumList(int num, Supplier<Integer> sup){
    
    
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < num; i++) {
    
    
            Integer n = sup.get();
            list.add(n);
        }
        return list;

    }
    @Test
    //Predicate<T>
    public void test2(){
    
    
        List<String> list = Arrays.asList("kzf","sdad","sdada","hwidh");
        List<String> strings = filterStr(list, (s -> s.length() > 3));
        for (String a:strings) {
    
    
             System.out.print(a+" ");
        }
    }
    //将满足条件的字符串,放入集合中
    public List<String> filterStr(List<String> list, Predicate<String> pre){
    
    
        List<String> list1 = new ArrayList<>();
        for (String a: list) {
    
    
            if(pre.test(a)){
    
    
                list1.add(a);
            }
        }
        return list1;
    }
    //Consumer<T> :处理字符串
    @Test
    public void test3(){
    
    
        nihao("dci",(m)-> System.out.println("你好"+m));
    }
    public void nihao(String name, Consumer<String> con){
    
    
        con.accept(name);
    }

    //Function<T,R>函数型接口:
    @Test
    public void test4(){
    
    
        String s = strHandler("\t\t\t你好我他", (str) -> str.trim());
        System.out.println(s);

    }
    public String strHandler(String str, Function<String,String> fun){
    
    
        return fun.apply(str);
    }
}

Output results

1. 22 30 82 84 54 49 62 38 55 2
2. sdad sdada hwidh
3. Hello dci
4. Hello me he

Some functional interfaces built into the system

public class FunctionalInterface {
    
    
    public static void main(String[] args) {
    
    

        // Predicate<T>              :     参数是T 返回值boolean  
        // 在后续如果一个接口需要指定类型的参数,返回boolean时可以指向 Predicate
        //          IntPredicate            int -> boolean
        //          LongPredicate           long -> boolean
        //          DoublePredicate         double -> boolean

        // Consumer<T>               :      参数是T 无返回值(void)
        //          IntConsumer             int ->void
        //          LongConsumer            long ->void
        //          DoubleConsumer          double ->void

        // Function<T,R>             :      参数类型T  返回值R
        //          IntFunction<R>          int -> R
        //          LongFunction<R>         long -> R
        //          DoubleFunction<R>       double -> R
        //          IntToLongFunction       int -> long
        //          IntToDoubleFunction     int -> double
        //          LongToIntFunction       long -> int
        //          LongToDoubleFunction    long -> double
        //          DoubleToLongFunction    double -> long
        //          DoubleToIntFunction     double -> int

        // Supplier<T> : 参数 无 返回值T
        // UnaryOperator<T> :参数T 返回值 T
        // BiFunction<T,U,R> : 参数 T、U 返回值 R
        // BinaryOperator<T> :参数 T、T 返回值 T
        // BiPredicate<T,U> :  参数T、U  返回值 boolean
        // BiConsumer<T,U> :    参数T、U 无返回值

        /**
         * 常用的 函数式接口
         * Predicate<T>、Consumer<T>、Function<T,R>、Supplier<T>
         */
    }
}

3、Stream Api

Several ways to create a stream

public class LambdaTest6 {
    
    
    @Test
    public void test1(){
    
    
        //创建Stream
        //1、可以通过Collection系列集合提供的stream()或parallelStream()
        List<String> list = new ArrayList<>();
        Stream<String> stream = list.stream();

        //2.通过Stream类中的静态方法of()
        Stream<String> aa = Stream.of("aa", "bb", "cc");

        //3.通过Arrays中的静态方法stream()获取数据流
        Person[] person = new Person[10];
        Stream<Person> stream1 = Arrays.stream(person);

        //4.创建无限流
        Stream<Integer> iterate = Stream.iterate(0, (x) -> x + 2);
        iterate.limit(10).forEach(System.out::println);

        //5.生成
        Stream.generate(()->Math.random()*100).limit(10).forEach(System.out::println);
    }

Generate test data

  List<Person> personList = Arrays.asList(
            new Person("张三", 14),
            new Person("李四", 28),
            new Person("王五", 38),
            new Person("张三", 59),
            new Person("张三", 75),
            new Person("张三", 75),
            new Person("张三", 75)
    );

Filter and slice


    //filter --接受Lambda,从流中排出某些元素
    @Test
    public void test1() {
    
    
        Stream<Person> stream = personList.stream()
                .filter((e) -> e.getAge() > 30);
        stream.forEach(System.out::println);
    }

    /**
     * 运行结果
     * Person{name='王五', age=38}
     * Person{name='张三', age=59}
     * Person{name='张三', age=75}
     * Person{name='张三', age=75}
     * Person{name='张三', age=75}
     */

    //limit--截断流,使其元素不超过给定数量
    @Test
    public void test2() {
    
    
        personList.stream()
                .filter((e) -> e.getAge() > 30)
                .limit(2)
                .forEach(System.out::println);
    }

    /**
     * 运行结果
     * Person{name='王五', age=38}
     * Person{name='张三', age=59}
     */

    //skip(n)跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与 limit(互补)
    @Test
    public void test3() {
    
    
        personList.stream()
                .filter((e) -> e.getAge() > 30)
                .limit(2)
                .skip(1)
                .forEach(System.out::println);
    }

    /**
     * 运行结果
     Person{name='张三', age=59}
     */

    //distinct --筛选,通过流所生成元素的hashCode()和equals()去除重复元素
    @Test
    public void test4() {
    
    
        personList.stream()
                .filter((e) -> e.getAge() > 30)
                .limit(2)
                .skip(1)
                .distinct()
                .forEach(System.out::println);
    }

    /**
     * 运行结果
     Person{name='张三', age=59}
     */


sort

 @Test
   @Test
    //自然排序
    public void test5(){
    
    
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        list.stream()
                .sorted()
                .forEach(System.out::println);
    }
    /**
     * 运行结果
     * 1
     * 2
     * 3
     * 4
     * 5
     */

Find/Match

   //findAny()和findFist()获取第一条数据,如果没有就返回为空。
    @Test
    public void test6() {
    
    
        Person person = personList.stream()
                .filter((e) -> e.getAge() > 30)
                .limit(2)
                .findAny()
                .orElse(null);
        System.out.println(person);
    }

    /**
     * 运行结果
     * Person{name='王五', age=38}
     */

    //map(T -> R):使用map取出姓名(字符串)
    @Test
    public void test7(){
    
    
        personList.stream()
                .map(Person::getName)
                .forEach(System.out::println);
    }

    /**
     * 运行结果
     * 张三
     * 李四
     * 王五
     * 张三
     * 张三
     * 张三
     * 张三
     */

Judgment method

  • Determine whether there is an element in the List collection that contains an element named Zhang San
  • Determine whether all entity names in the List collection contain the field "Zhang".
  • Determine whether there is a field in the List collection that does not contain "Zhang".
@Test
    public void test8(){
    
    
        boolean result = personList.stream().anyMatch((person -> person.getName().equals("张三")));
        boolean result1 = personList.stream().allMatch(person -> person.getName().contains("张"));
        boolean result2 = personList.stream().noneMatch(person -> person.getName().contains("张"));
        System.out.println(result);
        System.out.println(result1);
        System.out.println(result2);
    }
    /**
     * 运行结果
     * true
     * false
     * false
     */

statistical methods

  • reduce((T, T) -> T) 和 reduce(T, (T, T) -> T)
@Test
    public void test9(){
    
    
        Integer max = personList.stream().map(Person::getAge).reduce(Integer::max).get();
        Integer min = personList.stream().map(Person::getAge).reduce(Integer::min).get();
        Integer sum = personList.stream().map(Person::getAge).reduce(0,Integer::sum);

        System.out.println(max);
        System.out.println(min);
        System.out.println(sum);
    }
    /**
     * 运行结果
     * 75
     * 14
     * 364
     */

Guess you like

Origin blog.csdn.net/lzfaq/article/details/122060851