Lambda表达式

1.内部类

内部类有成员内部类、局部内部类(定义在方法内部的)、匿名内部类、静态内部类

2.匿名内部类

匿名内部类,顾名思义就是没有名称的内部类。

//匿名内部类
Runnable r1 = new Runnable(){
	@Override
	public void run(){
		System.out.println("Hello World!");
	}
};
// 其中r1 的功能和R2类相同        
class R2 implements Runnable{
     @Override
     public void run() {
         System.out.println("Hello World!"); 
     }
 }
 Runnable r2 = new R2();
 r1.run();
 r2.run();

3.lambda表达式

lambda是一个匿名函数,可以把lambda表达式理解为 一段可以传递的代码。
->:java8引入的新操作符,称为lambda操作符
->左侧:lambda表达式的参数列表
->右侧:lambda表达式所需执行的功能。

3.1 函数式接口@FunctionalInterface

只包含一个抽象方法的接口,称为函数式接口,可以用lambda表达式创建该接口的对象。典型的函数式接口有Runnable接口。

3.2 lambda表达式语法

import org.junit.Test;
import java.util.Comparator;
import java.util.function.Consumer;
/**
 * @Description:
 * @Author: cc
 * @CreateDate: 2018/11/7 15:01
 */
public class LambdaDemo {

    /**
     * lambda格式一:无参无返回值
     */
    @Test
    public void test1(){
        //匿名内部类
        Runnable r1 = new Runnable(){
            @Override
            public void run(){
                System.out.println("Hello World!");
            }
        };
    // Lambda 表达式
        Runnable r2=()->System.out.println("Hello!");
    }

    /**
     * lambda格式二:一个参数无返回值
     * ()可以省略不写:Consumer<String> consumer = x->System.out.println(x);
     */
    @Test
    public void test2(){
        Consumer<String> consumer = (x)->System.out.println(x);
        consumer.accept("hello");
    }

    /**
     * lambda格式三:多个参数有返回值,函数体为多条语句
     * 需要写{}大括号
     */
    @Test
    public void test3(){
        Comparator<Integer> com= (x,y)->{
          System.out.println(x);
          return Integer.compare(x,y);
        };
        System.out.println(com.compare(4,7));
    }
    /**
     * lambda格式四:有返回值,函数体为一条语句
     * {}大括号可以省略不写
     */
    @Test
    public void test4(){
        Comparator<Integer> c = (x,y)->Integer.compare(x,y);
        System.out.println(c.compare(2,5));
    }
}

4. 应用

4.1 自定义运算

@FunctionalInterface
    public interface MyFun {
        public Integer getValue(Integer t);
    }
     // 将函数式接口作为参数传递
    public Integer operator(Integer num,MyFun myFun){
        return myFun.getValue(num);
    }
    @Test
    public void exercise1(){
        // 使用函数式编程实现平方操作
        Integer e= operator(100,(x)-> x * x);
        Integer s = operator(222,(x)->20+x);
        System.out.println(e +"\n"+s);
    }

4.2 排序

调用Collections.sort,比较两个Employee,先按年龄排序,年龄相同按姓名排序


    private List<Employee> employees = Arrays.asList(
            new Employee("小王",23,"111"),
            new Employee("小张",22,"111"),
            new Employee("哈哈",100,"111"));   
    @Test
    public void exercise2(){
        Collections.sort(employees,(e1,e2)->{
            if (e1.getYear()==e2.getYear())
                return e1.getName().compareTo(e2.getName());
            else
                return Integer.compare(e1.getYear(),e2.getYear());
        });
        for (Employee e:employees)
            System.out.println(e);
         /** 输出
         * Emloyee{name='小张', year='22', position='111'}
         * Emloyee{name='小王', year='23', position='111'}
         * Emloyee{name='哈哈', year='100', position='111'}
         */
    }
    

4.3 泛型函数式接口

 @FunctionalInterface
    public interface MyFun2<T,R>{
        public R getValue(T t1,T t2);
    }
    public void op(Long l1,long l2,MyFun2<Long,Long> mf){
        System.out.println(mf.getValue(l1,l2));
    }
    @Test
    public void exercise3(){
        op(100L,22L,(x,y)->x+y);
    }

5. java 8内置函数式接口

四大核心函数式接口

接口方法说明
Consumervoid accept(T t)消费型接口
SupplierT get()供给型接口
Function<T, R>R apply(T,t)函数型接口
PredicateBoolean test(T t)断言型接口
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
 * @Description:
 * @Author: cc
 * @CreateDate: 2018/11/7 18:07
 */
public class java8Inner {

    public void happly(double m, Consumer<Double> con){
        con.accept(m>100?m-1:m+1);
    }
    @Test
    public void test1(){
        happly(100,m->System.out.println("happly "+m*2));
        //结果为: happly 202.0
    }
    
    //生成指定个数的整数集合
    public List<Integer> getNumList(int num, Supplier<Integer> supplier){
        List<Integer> list = new ArrayList<>();
        for (int i=0;i<num;i++){
            Integer n = supplier.get();
            list.add(n);
        }
        return list;
    }
    @Test
    public void test2(){
        List<Integer> numList= getNumList(10,()->(int)(Math.random()*100));
        for (int l:numList)
            System.out.print(l+" ");
    }
	//处理字符串
    @Test
    public void test3(){
        String s1 = handlerStr("222  ",(s)->s.trim());
        String s2 = handlerStr("222 www",s->s.substring(2,1));
        System.out.println(s1+" "+s2);
    }
    public String handlerStr(String s, Function<String,String> fun){
        return fun.apply(s);
    }
    
    // 返回大于3的字符串集合
    @Test
    public void test4(){
        List<String> list = Arrays.asList("22","sssssss","hhh");
        List<String> newList = filterStr(list,(s)->s.length()>3);
        for(String s:newList)
            System.out.println(s);
    }
    public List<String> filterStr(List<String> list, Predicate<String> predicate){
        List<String> stringList = new ArrayList<>();
        for (String str:list){
            if (predicate.test(str))
                stringList.add(str);
        }
        return stringList;
    }
}

6. 方法引用

如果lambda体中的内容已经实现,我们可以使用方法引用。lambda体中的调用的参数列表和返回值类型要与函数式接口中抽象方法的参数列表和返回值类型保持一致。
主要有三种格式:

  • 对象::实例方法名
  • 类::实例方法名
  • 类::静态方法名
import org.junit.Test;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
 * @Description:
 * @Author: cc
 * @CreateDate: 2018/11/7 19:49
 */
public class MethodRefercen {
	 // 方法引用1 —— 对象::实例方法名 
    @Test
    public void test1(){
        Consumer<String> c1 = (x)->System.out.println(x);   
        Consumer<String> consumer1= System.out::println;
    }

	// 方法引用2 —— 类::静态方法名 
    @Test
    public void test2(){
        Comparator<Integer> com = (x,y)->Integer.compare(x,y);
        Comparator<Integer> com2 = Integer::compare;   
    }
     //方法引用3 —— 类::实例方法
    // 若lambda体中的第一参数是实例方法的调用者,第二参数是实例方法的参数时
    @Test
    public void test3(){
        BiPredicate<String,String> biPredicate = (x,y)->x.equals(y);
        BiPredicate<String,String> bp2 = String::equals;
    }
}

7.构造器引用

格式为: 类名::new
需要调用构造器的参数列表 和 函数式接口 抽象参数列表一致

public void test(){
	Supplier<Employee> sup1 = ()->new Employee();
	Supplier<Employee> sup2 = Employee::new;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值