• 17、lambda表达式


    一、简介

      lambda表达式允许你通过表达式来代替功能接口,lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块),它还增强了集合库,java.util.function包java.util.stream包

      流就如同迭代器,但附加了许多额外的功能。

    二、基本语法

      (parameters)->expression

      或

      (parameters)->{statements;}

    例子:输出的->代表一个Consumer接口用来接收一个输入对象并处理,如果需要访问类型T的对象,并对其执行某些操作,就可以使用这个接口。

    public class A {
        public static void main(String[] args) {
            IA i=(int c,int d)-> System.out.println(c);
            i.run(100,200);
        }
    }
    interface IA{
        public void run(int a,int b);
    }

    三、例子

      遍历数组(数组变成列表,使用列表的forEach方法遍历,其中System.out::println用来输出当前调用它的对象内容)

    public class B {
        public static void main(String[] args) {
            String names[]={"JAKE","MIKE","ROSE"};
            List<String> list= Arrays.asList(names);//数组变成list
            list.forEach(n-> System.out.println(n));
            list.forEach(System.out::println);
        }
    }

      字符数组排序,—>代表Comparator接口用来比较字符串

    public class C {
        public static void main(String[] args) {
            String names[]={"MIKE","JAKE","ROSE"};
            Arrays.sort(names,(String s1,String s2)->s1.compareTo(s2));
            List<String> list=Arrays.asList(names);
            list.forEach(System.out::println);
        }
    }

    四、Lambda内置函数接口和Stream和parallelStream操作(并行流)

      Stream(这个Stream不是之前那个流,而是lambda下的流)是对集合的包装,通常和lamabda一起使用,是java8的新特性,它不是集合元素,不是数据结构,并不保存数据,它是有关算法和计算的,它更像一个高级版本的Iterator。原始版本的Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如“过滤掉长度大于10的字符串”、“获取每个字符串的首字母”等,Stream会隐式的在内部进行遍历,做出相应的数据转换。Stream就如同一个迭代器:单向,不可重复,数据只能遍历一次,遍历过一次后即用尽了。

      Stream和迭代器不同点:Stream可以支持并行化操作,迭代器只能命令式、串行化操作(在迭代器中,每个item读完之后,再读下一个,而Stream则将数据分段,每个段都在不同的线程中处理)

      Stream的另一个特点是:数据源本身可以是无限的(元素个数不限)。

      使用lambdas可以支持许多操作,如 map(汇总mapreduce)、filter(过滤)、limit(限制)、sorted、count、min、max、sum、collect等等。

      使用Stream使用懒运算,他们并不会真正的读取所有数据,遇到像getFirst()这样的方法就会结束 链式语法。

    接口一:consumer:

     consumer接口使用:consumer接口下自带一个方法accept(),用来接收对象传给consumer变量p,然后在后面对其操作。foreach方法需要consumer形参,对consumer中元素遍历

    package com.zxc.P;
    
    import org.junit.Test;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Consumer;
    
    /**
     * Created by Administrator on 2018/2/9 0009.
     */
    public class D {
       private List<Person> list=new ArrayList<Person>(){
            {
                add(new Person(100,"JACK"));
                add(new Person(200,"MIKE"));
                add(new Person(300,"ROSE"));
            }
        };
        @Test
        public void test(){
            Consumer<Person> consumer=(p)->{System.out.println(p.getName());};
            consumer.accept(new Person(200,"MIKE"));
        }
        @Test
        public void test1(){
            Consumer<Person> consumer=(p)->{
                p.setAge(p.getAge()+10);
                System.out.println(p.getAge());
            };
            list.forEach(consumer);
        }
    }
    
    class Person{
        private int age;
        private String name;
    
        public Person() {
        }
    
        public Person(int age, String name) {
            this.age = age;
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

    接口二、Streams-Predicate接口(断言、断定、判断)

      java.util.fuction.Predicate<T>接口定义了一个名叫test的抽象方法,它接收泛型T对象,并返回一个boolean。在需要表示一个涉及类型T的布尔表达式时,就可以使用这个借口。比如:可以定义一个接收String对象的Lambda表达式。

      1、过滤器:filter

        可以接受一个predicate接口类型的变量,并将所有流对象中的元组进行过滤。该操作是一个中间操作,因此它允许我们在返回结果的基础上再进行其他的流操作(forEach)

       以下是一个过滤器filter,用来过滤100到200之间的

    package com.zxc.P;
    import org.junit.Test;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Predicate;
    /**
     * Created by Administrator on 2018/2/9 0009.
     */
    public class E {
        private List<Person> list=new ArrayList<Person>(){
            {
                add(new Person(100,"JACK"));
                add(new Person(200,"MIKE"));
                add(new Person(300,"ROSE"));
            }
        };
        @Test
        public void test(){
            //Predicate<Person> predicate=(p)->(p.getAge()>100);
            //Predicate<Person> predicate1=(p)->(p.getAge()<300);
            list.stream()
                    .filter((p)->(p.getAge()>100))
                    .filter((p)->(p.getAge()<300))
                    .forEach((p)-> System.out.println(p.getAge()));
        }
    }

      2、test()方法用来测试数据,negate()方法去数据反向

     public void test2(){
            Predicate<String> predicate=(p)->(p.length()>3);
            System.out.println(predicate.test("哈尔滨"));//true
            System.out.println(predicate.negate().test("哈尔滨"));//false
    
            Predicate<String> predicate1= Objects::nonNull;//静态方法,判断是否为空无堆
            System.out.println("--"+predicate1.test("123"));
    
            Predicate<String> predicate2=Objects::isNull;//静态方法,判断是否为空有堆
            System.out.println("--"+predicate2.test("456"));
    
            Predicate<String> predicate3=String::isEmpty;//静态方法,判断是否为空有堆
            System.out.println("--"+predicate3.test("456"));
        }

      3、limit()方法取出限制数量的数据,限制的顺序对过滤出来的信息有影响

     public void test4(){
            Predicate<String> predicate=(p)->(p.length()>3);
            list.stream()
                    .limit(2)
                    .forEach((p)-> System.out.println(p.getName()));
            list.stream()
                    .limit(1)
                    .filter((p)->p.getName().equals("ROSE"))
                    .forEach((p)-> System.out.println(p.getName()));
        }

      4、match方法用来匹配

     public void test7(){
            System.out.println(StringCollection.stream().anyMatch((p)->p.startsWith("J")));
            System.out.println(StringCollection.stream().allMatch((p)->p.startsWith("J")));
            System.out.println(StringCollection.stream().noneMatch((p)->p.startsWith("J")));
        }

    接口三、comparator(比较)

      comparator是老java中的经典接口,新的java在此之上添加了多种默认方法。

      compare方法用来比较字符串,返回前一个参数首字符减去后一个参数首字符的数字

      sorted()方法可以比较两个参数,让其进行比较。

      collect()方法可以将结果集收集成一个数组列表。

      max() min()方法取最大最小值

       public void test(){
            Comparator<Person> comparator=(p1,p2)->p1.getName().compareTo(p2.getName());
            System.out.println(comparator.compare(new Person(100,"MIKE"),new Person(200,"Rose")));
            List<Person> nlist=list.stream()
                    .sorted((p1,p2)->p1.getAge()-p2.getAge()>0?p1.getName().compareTo(p2.getName()):p1.getAge()-p2.getAge())
                    .limit(3)
                    //.max((p1,p2)->p1.getAge()-p2.getAge()).get.getName();
                    .collect(Collectors.toList());
                    //.forEach((p)-> System.out.println(p.getName()));
            System.out.println(nlist.size());
        }

    接口四、function流水线接口(Suppliers接口同function一样,但是没有输入参数)

    利用Suppliers接口来实例化一个对象

    //初始化默认构造器,不可以初始化非默认的  
    public void test5(){
            Supplier<Person> supplier=Person::new;
            Person p=supplier.get();
            p.setName("MIke");
        }

      apply()方法:应用:类似于Predicate接口下的test()方法,用于放入数据到流水线中    

      andThen()流水线下一步操作

     public void test(){
            Function<String,Integer> function=Integer::valueOf;
            Function<String,String> function1=function.andThen(String::valueOf);
            System.out.println(function.apply("123")) ;
        }

      map()方法:分类。是一个对于流对象的中间操作,通过给定的方法,它能够把流对象中的每一个元素对应到另外一个对象上。

      public void test1(){
            List<String> list1=list.stream()
                    .map(Person::getName)//定义就是在聚集的时候执行该对象的定义
                    .collect(Collectors.toList());
            list1.forEach((s)-> System.out.println(s));
    
            System.out.println(list.stream()
                    .map(Person::getName)//定义就是在聚集的时候执行该对象的定义
                    .collect(Collectors.joining("*")));
        }

      reduce():汇总、折叠操作。(map将集合类(例如列表)元素进行转换,reduce函数可以将所有值合并成一个,类似于SQL中的sum() count()  avg()等聚集函数,接收多个值,返回一个值)

        @Test
        public void test3(){
            List<Integer> costBeforeTax = Arrays.asList(100,200,300,400,500);
            System.out.println(costBeforeTax.stream()
                    .map((a)->a*0.5+a)
                    .reduce((sum,a)->sum+=a)
                    .get());
        }

    接口五:Optional接口

        public void test6(){
            Optional empty=Optional.ofNullable(null);
            System.out.println(empty);
    
            Optional<String> s=Optional.ofNullable(null);
            System.out.println(s.isPresent());
            //System.out.println(s.get());
            System.out.println(s.orElse("fallback"));
        }

    接口六:ToIntFunction:

      方法:summaryStatistic用来计算统计

        public void test(){
            List<Integer> numbers= Arrays.asList(1,2,3,4,5,6,7,8,9);
            IntSummaryStatistics is=numbers.stream().mapToInt((x)->x+1).summaryStatistics();
            System.out.println(is.getCount());
            System.out.println(is.getAverage());
            System.out.println(is.getMax());
            System.out.println(is.getMin());
            System.out.println(is.getSum());
        }

    五、lambda的环绕式

    package com.zxc.P;
    import org.junit.Test;
    /**
     * Created by Administrator on 2018/2/9 0009.
     */
    public class I {
        @Test
         public void test(){
            System.out.println("start");
            System.out.println(ok((p)->p+p+p+p+p+p));
            System.out.println("end");
         }
         @FunctionalInterface
        public interface Iok{
             String process(String s);
         }
         public String ok(Iok iok){
             return iok.process("ok");
         }
    }
  • 相关阅读:
    通俗理解乐观锁和悲观锁
    面试系列-HashMap和Hashtable的区别
    单点登录原理与实现
    CodeReview常见代码问题
    漫画:什么是冒泡排序?
    Redis 和 Memcached 的区别
    动态图文了解 8 大排序算法
    分布式系统常见的事务处理机制
    面试系列-String,StringBuffer,StringBuilder三者区别
    面试系列-高并发之synchronized
  • 原文地址:https://www.cnblogs.com/television/p/8433183.html
Copyright © 2020-2023  润新知