JavaSE-Lambda表达式-01-201804

3 篇文章 0 订阅

JavaSE-Lambda表达式-01-201804

初步学习

(since JDK 1.8)

1.函数式编程:(x->f(x)),x到f(x)的映射关系。f(x)的值只取决于x。


函数式编程命令式编程
关注点映射关系实现过程
x是否可变
有无循环无(可使用递归)
并行便利度
写法简洁度

2.函数接口

概念:只有一个抽象方法的接口。(用作Lambda表达式的类型)

注:    a. jdk1.8后接口内可以有非抽象方法,此时函数接口实现不会对接这些方法。

        b.当接口含有与Object内public类型方法相同的抽象方法时,这些方法不会影响函数接口的实现。

        (原因:i.  所有函数接口的实现类必然也是Object的子类;

                     ii. 接口内抽象方法默认为public,如Object类中的protected Object clone()此时权限将扩大,与Object类中

                         clone() 方法签名不同,会影响影响函数接口的实现。)

3.Lambda表达式概念

实质是一个匿名函数(可传递的代码块)。

例: Runnable noArgs=()->System.out.println("noArgs");

解析:Runnable 接口只有一个abstract方法void run(),该接口可作为函数接口。()->System.out.println("noArgs"); 表示一个实  现了Runnable接口并重写其run()方法为System.out.println("noArgs")的类生成的一个对象。

4.Lambda表达式语法   

            a.无参单行

            Runnable noArgs=()->System.out.println("noArgs");

           b.无参多行

            Runnable noArgs=()->{

                System.out.println("no");

                System.out.println("Args");            

            };

           c.单参隐式

           ActionListener al=event->System.out.println("clicked");

           d.多参隐式

            BinaryOperator<Integer> add=(x,y)->x+y;

           e.显式

            Comparator<String> comp=(String s1,String s2)->s1.length()-s2.length();

            (此处类型String,可由泛型<String>推导出,实际可写作隐式。仅作展示显式语法)

           f.带return字句

BinaryOperator<Integer> doubleX=(x,y)->{
    if(x>y){
       return x*2;
    }
    return y*2;
 };

            (注:若lambda表达式返回类型不为空,且在if中使用return字句,必须保证该代码块始终有返回值。)

5.Lambda表达式引用外部变量

    jdk1.7及以前版本,局部内部类引用的外部变量必须为常量(final),而jdk1.8后局部内部类和Lambda表达式中对外部变量声明的要求放宽,不要求强制声明为final,但实际仍然为常量(Effectively final)。

int m=9;
//m=10; 若添加本行则编译不过,原因是lambda表达式引入的外部变量必须为实际常量(effective final)
//eclipse报错Local variable m defined in an enclosing scope must be final or effectively final
Tryone to=n->n*m;                //Tryone是自定义的函数接口,接口方法int one(int x)
//Tryone to=n->{m=m+1;return m;};
System.out.println(to.one(5));

6.方法引用

概念:使用lambda表达式调用已存在的方法.

例:Runnable runQuo=System.out::println; // <==> ()->System.out.println(); 

将要使用的example环境:

interface Tryone {
	int one(int n);
}
interface Two<T>{
	T two(int n);
}

@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

class TryAll implements Tryone{
	int n;
	public TryAll(int n) {this.n=n;}
	public TryAll() {}
	
	@Override
	public int one(int n) {
		// TODO Auto-generated method stub
		return n*n;
	}
	
	@Override
	public String toString() {
		return "TryAll [n=" + n + "]";
	}
	
}

    a.引用类的静态方法--Class::staticMethod

        Tryone to2=Math::abs;   //取绝对值 [注意使用方法引用时参数类型需一致]/<==> n->Math.abs(n);

    b.引用对象的实例方法--object::instanceMethod

        Tryone to3=new TryAll();

        Tryone to4=to3::one;

    c.引用类型对象的实例方法--Class::instanceMethod

        Arrays.sort(testStr, String::compareToIgnoreCase);

        //等价于 Arrays.sort(testStr, (s1,s2)->s1.compareToIgnoreCase(s2)); //按字典顺序排序-lambda表达式的一般形式

    注意:  1.引用对象的实例方法时,对象可以是this、super.

                2.对于引用类型对象的实例方法,若实例方法是泛型的,可能需要在::前加泛型 。   

                3.对于引用类型对象的实例方法,若有多个同名重载方法,编译器会尝试从上下文中找出正确方法。  

7.构造方法引用-- Class::new

     应选择带泛型返回值或所需类型返回值的函数接口.

    a.无参构造

        Supplier<TryAll> supplier=TryAll::new;                //Supplier接口是jdk1.8新增java.util.function包中的函数接口

        System.out.println(supplier.get().toString()); 

    b.带参构造

        Two<TryAll> tryTwo=TryAll::new;

        System.out.println(tryTwo.two(2).toString());

8.数组构造方法引用--TypeName::new

    数组的构造方法引用的语法则比较特殊,可以假想存在一个接收int参数的数组构造方法。

    即参数为int,返回类型为数组的函数接口。

    Two<int[]> arrayMaker = int[]::new;

    int[] array = arrayMaker.two(5);         // 创建数组 int[5]

    System.out.println(Arrays.toString(array));


参考资料:http://www.cnblogs.com/figure9/p/java-8-lambdas-insideout-language-features.html

                http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值