初识java8 lambda表达式(一)

java8中最大的变化就是引入了Lambda表达式,这是一种函数式编程的方式。

1.lambda表达式的形式

java8的lambda表达式语法如下:

(paramters)->expression;

或者

 (parameters)->{statements;};

例如:

()->10;

(x)->x+10;

(x,y)->x+y;

(int x,int y)->x+y;

(int x)->x+10;

或者:

()->{10;}

(x)->{x+10;}

(x,y)->{x+y;}

(int x,int y)->{x+y;}

(int x)->{x+10;}

lambda表达式由三部分组成:

1.parameters:方法中的形参列表,这里的参数是函数式接口里的参数,参数类型可以明确声明也可以隐藏。

2.->:可以理解为“被用于”的意思

3.方法体:可以是表达式也可以是代码块,是函数式接口里方法的具体实现。代码块根据需要使用的方法自行定义是否返回值。

2.lambda表达式的具体实现

2.1 遍历集合

List list= Arrays.asList("lamdbas","Default");
list.forEach(n->{System.out.println(n); System.out.println(n+"23"); });

执行结果如下:

lamdbas
lamdbas23
Default
Default23

2.2带参函数的简写

List list= Arrays.asList("da","abc","c","q","d");
Collections.sort(list,(String a,String b)->{
    if(a==null){
        return 1;
    }else if(b==null){
        return -1;
    }else{
        return a.length()-b.length();
    }
});
list.forEach(System.out::println);

执行结果如下

c
q
d
da
abc

简写的依据

能够使用lambda的依据就是必须有相应的函数接口(函数接口,是指内部只有一个抽象方法的接口)。

2.3 自定义函数接口

自定义函数接口很简单,只要编写一个只有一个抽象方法的接口即可。

@FunctionalInterface  //自定义函数接口注解,可写可不写,写了会检查是否符合函数接口规范
interface Converter<F,T>{
    T convert(F a);
}

//使用lambda表达式调用

Converter<String,Integer> a=str->{System.out.println(str);return Integer.valueOf(str);};
a.convert("1231");

执行结果如下

1231

解释:此功能的主要作用是输出string对象并将string类型的对象转换成Integer;

标准的函数式接口有

  • Function<T, R>:接受一个参数T,返回结果R

  • Predicate<T>:接受一个参数T,返回boolean

  • Supplier<T>:不接受任何参数,返回结果T

  • Consumer<T>:接受一个参数T,不返回结果

  • UnaryOperator<T>:继承自Function<T, T>,接受一个参数T,返回相同类型T的结果

  • BiFunction<T, U, R>:接受两个参数T和U,返回结果R

  • BinaryOperator<T>:继承自BiFunction<T, T, T>,接受两个相同类型T的参数,返回相同类型T的结果

  • ……

3.方法引用

方法引用式lambda表达式的一种简化写法。具体的结构如下:

          Object::methodName

左边式类名或者实例名,中间式方法引用符号"::",右边式相应的方法名,方法引用分为三类:

1.静态方法引用

public class StaticFunction {
    @FunctionalInterface
    public interface  Converter<T,F>{
        F convert(T a);
    }
    static String func(String a){
        return a+"abc";
    }
    @Test
    public void test(){
        Converter<String,String> a=StaticFunction::func;
        System.out.println(a.convert("123"));

    }
}

结果如下

123abc

2.实例方法引用

public class StaticFunction {
    @FunctionalInterface
    public interface  Converter<T,F>{
        F convert(T a);
    }
    String func(String a){
        return a+"abc";
    }
    @Test
    public void test(){
        StaticFunction a=new StaticFunction();
        Converter<String,String> b=a::func;
        System.out.println(b.convert("123"));

    }
}

结果如下

123abc

3.构造方法引用

//创建一个Animal的父类

@Data
public class Animal {
    private String name;
    private int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void behavior(){

    }

}

//创建一个Dog的子类

public class Dog extends Animal{
    public Dog(String name,int age){
        super(name,age);
    }
    @Override
    public void behavior(){
        System.out.println("this is a dog");
    }
}

//创建一个Bird的子类

public class Bird extends Animal {
    public Bird(String name, int age) {
        super(name, age);
    }
    @Override
    public void behavior(){
        System.out.println("this is a bird");
    }
}

//定义工厂的函数式接口

@FunctionalInterface
interface Factory<T extends Animal>{
    T create (String name,int age);
}

//创建测试

@Test
public void test(){
    Animal.Factory<Animal> dogFactory=Dog::new;
    Animal dog=dogFactory.create("a",1);
    if(dog instanceof Dog){
       dog.behavior();
    }
    Animal.Factory<Bird> birdFactory=Bird::new;
    Bird bird=birdFactory.create("b",2);
    if(bird instanceof Bird){
       bird.behavior();
    }
}

结果如下

this is a dog
this is a bird

4.lambda的作用域

在lambd表达式外部的局部变量会被JVM隐式的编译成final类型,因此只能访问外而不能修改

public class ReferenceTest {

@Test
    public void test() {
 
        int n = 9;
        Calculate calculate = param -> {
            //n=10; 编译错误
            return n + param;
        };
        calculate.calculate(1);
    }
 
    @FunctionalInterface
    interface Calculate {
        int calculate(int value);
    }
 
}
 

在lambda表达式内部,对静态变量和成员变量可读可写

public class Reference {
    @FunctionalInterface
    public interface Refer{
        int print();
    }
    public int count=1;
    public static int sum=2;
    @Test
    public void test(){
        System.out.println(count);
        System.out.println(sum);
        Refer re=()->{
            count=3;
            sum=4;
            return count+sum;
        };
        System.out.println(re.print());
        System.out.println(count);
        System.out.println(sum);
    }
}

输出结果为

1
2
7
3
4

需要注意的是只有在执行了re.print()这个方法之后成员变量和静态变量的值才会改变。

原创文章 46 获赞 24 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_39892293/article/details/87163677