zoukankan      html  css  js  c++  java
  • 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");
         }
    }
  • 相关阅读:
    Android的数据存储
    Servlet第一天
    JavaScript高级程序设计读书笔记(3)
    Interesting Papers on Face Recognition
    Researchers Study Ear Biometrics
    IIS 发生意外错误 0x8ffe2740
    Father of fractal geometry, Benoit Mandelbrot has passed away
    Computer vision scientist David Mumford wins National Medal of Science
    Pattern Recognition Review Papers
    盒模型bug的解决方法
  • 原文地址:https://www.cnblogs.com/television/p/8433183.html
Copyright © 2011-2022 走看看