JAVA SE面向对象编程之Lambda

不知道使用的感觉好高大上,使用的感觉也就那样(编程容易)。

简单描述,Lambda运行使用简洁的代码来创建只有一个抽象方法接口的实例(符合这种要求的接口我们把它们叫做函数式接口,JAVA8提供了一些函数式接口可以参考https://www.cnblogs.com/sxrtb/p/12685052.html

简单使用例子来说明

public class ConsumerTest {
    public static void main(String[] args) {
        ProcessArr processArr = new  ProcessArr();
        int[] intarr = new int[]{1,2,3,4,6,5};
        processArr.process(intarr,(int[] t)-> {
                    for (int ti:t) {
                        System.out.println(ti);
                    }
                }
        );

    }
}
class ProcessArr{
    public  void process(int[] target ,ConsumerInterface consumerInterface){
        consumerInterFact.accpet(target);
    }
}

interface ConsumerInterface{
    void accpet(int[] target);
}

在这个例子中,就是将使用匿名内部类的地方使用了Lambda替换

 

Lambda使用:

  参数列表,用括号()括起来,若只有一个参数,可以省略括号

  ->

  方法体,用花括号{}括起来,只有一条语句,则可以省略{},且此时可以省略return字段

 

方法体中只有一条语句时,可以使用方法引用构造器引用(就是一些简编代码的编程方式)

 

1.引用类方法

public class ClassMethodRefTest {
    public static void main(String[] args) {
        Converter classMethodRef = Integer::valueOf;
        //Converter classMethodRef = t -> Integer.valueOf(t);相当于上面的编程
        int a = classMethodRef.Convert("123");
        System.out.println(a);
    }
}
interface Converter{
    int Convert(String s);
}

2.对象引用实例方法

public class InstanceMethodRefTest {
    public static void main(String[] args) {
        Converter converter = "abcd"::indexOf;
        //Converter converter = t -> "abcd".indexOf(t);相当于上面的编程
        int s = converter.Convert("b");
        System.out.println(s);

    }
}

interface Converter{
    int Convert(String s);
}

3.类引用实例方法

public class ClassInstanceMethodRefTest {
    public static void main(String[] args) {
        ConverterT converter = String::substring;
        //ConverterT converter = (a,b,c) ->a.substring(b,c);相当于上面的编程
        String s = converter.sub("abcdef",1,3);
        System.out.println(s);
    }
}

interface ConverterT{
    String sub(String a,int b,int c);
}

4.应用构造器

  简单说一下,若函数式接口的抽象方法返回一个对象,而该方法中的参数和对象所在类中定义的构造器有相同的形参列表,则直接使用返回对象的名称::new就行

 

刚开始看的或,可能会感觉不好理解,简单说一下我是怎么理解的吧

  1.先看返回参数,若函数式接口的返回值和我们知道的任意方法的返回值相同,首先我们就可以考虑用我们知道的方法来完成我们抽象方法的实现

   2.参数填坑,将函数式接口中的方法参数填写到我们知道的方法的对象(若调用类方法,则不需要对象),方法列表,若刚好能放进去,恭喜你,你可以使用引用的方式完成Lambda的编写了

 

 若明白了这个点,也会发现一个有趣的问题。

public class LambdaT {
    public static void main(String[] args) {
        AInterface aInterface = A::test1;
        aInterface.printString(new A(),1,2);
    }
}
class A{
    public void test1(int b,int c){
        System.out.println("test1 b c isntance");
    }
}
interface AInterface{
    public void printString(A a,int b,int c);
}
public class LambdaT {
    public static void main(String[] args) {
        AInterface aInterface = A::test1;
        aInterface.printString(new A(),1,2);
    }
}

class A{
   public static void test1(A a,int b,int c){
        System.out.println("test1 a b c static");
    }
}
interface AInterface{
    public void printString(A a,int b,int c);
}

 当然,顺着这个思路,其实大家要是细看的话(或者说自己写了的话),会发现例子2和例子3有点相似,我们这里来改变例子2,让它和例子3相同

public class InstanceMethodRefTest {
    public static void main(String[] args) {
        Converter converter = String::indexOf;
        //Converter converter = (t,tt) -> t.indexOf(tt);相当于上面的编程
        int s = converter.Convert("abcd","b");
        System.out.println(s);
    }
}

interface Converter{
    int Convert(String s,String ss);
}

 所以总结来看,其实例子1,例子2和例子3其实时一样的

 

5.Lambda和匿名内部类的区别

  Lambda不能调用接口中的默认方法,但是匿名内部类可以(个人绝对知道这点就可以了,其他的就是Lambda受限于函数式接口带来的)

 

posted on 2020-04-12 15:46  xingshouzhan  阅读(176)  评论(0编辑  收藏  举报

导航