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");
     }
}
原文地址:https://www.cnblogs.com/television/p/8433183.html