【JavaSE 九】Lambda

九、Lambda

初识Lambda

​ Lambda表达式可以看成是匿名类一点点演变过来

​ Lambda 其实就是匿名方法,这是一种把方法作为参数进行传递的编程思想。

​ 虽然代码是这么写,但是,Java会在背后,悄悄的,把这些都还原成匿名类方式

​ 引入Lambda表达式,会使得代码更加紧凑,而不是各种接口和匿名类到处飞。

​ Lambda表达式虽然带来了代码的简洁,但是也有其局限性。

​ 可读性差,与啰嗦的但是清晰的匿名类代码结构比较起来,Lambda表达式一旦变得比较长,就难以理解。

​ 不便于调试,很难在Lambda表达式中增加调试信息,比如日志。

​ 版本支持,Lambda表达式在JDK8版本中才开始支持

​ Lambda比较适合用在简短的业务代码中,并不适合用在复杂的系统中,会加大维护成本。

无参无返回值

/***
 * lambda格式:(形式参数) -> {代码块}
 */
public class Txt {
    public static void main(String[] args) {
        //无参无返回值,无参留空即可
        filter(()->{System.out.println("我是lambda体");
                    System.out.println("我是代码块中的多个语句");});
    }

    public static void filter(Checker ch) {
        ch.checker();
    }
}

interface Checker {
    //无参无返回值的抽象方法
    public  void checker();
}

有参无返回值

/***
 * lambda格式:(形式参数) -> {代码块}
 */
public class Txt {
    public static void main(String[] args) {
        //有参无返回值,如果参数有且仅有一个,那么小括号可以省略
        filter((t,h)->{System.out.println("我是lambda体"+t);
                    System.out.println("我是代码块中的多个语句"+h);});
    }

    public static void filter(Checker ch) {
        ch.checker(3,8);
    }
}

interface Checker {
    //有参无返回值的抽象方法
    public  void checker(int i,int j);
}

有参有返回值

/***
 * lambda格式:(形式参数) -> {代码块}
 */
public class Txt {
    public static void main(String[] args) {
        //有参有返回值,如果参数有且仅有一个,那么小括号可以省略
        filter((t,h)->{System.out.println("我是lambda体"+t);
                    System.out.println("我是代码块中的多个语句"+h);
                    return "我是返回值";});
    }

    public static void filter(Checker ch) {
        System.out.println(ch.checker(3,8));
    }
}

interface Checker {
    //有参有返回值的抽象方法
    public  String checker(int i,int j);
}

省略写法

/***
 * lambda格式:(形式参数) -> {代码块}
 */
public class Txt {
    public static void main(String[] args) {
        //有参有返回值,如果代码块的语句只有一条,可以省略大括号和分号,甚至是return
        //省略前
        filter((t,h)-> {
           return t + h;
        });
        //省略后
        filter((t,h)-> t + h);
    }

    public static void filter(Checker ch) {
        System.out.println(ch.checker(3,8));
    }
}

interface Checker {
    //有参有无返回值的抽象方法
    public  int checker(int i,int j);
}

Lambda方法引用

引用静态方法

​ 把静态方法,以参数的形式传递给函数式接口的抽象方法。通俗点,把静态方法体赋给函数式接口的方法体

​ 这个静态方法必须和函数式接口中方法的返回值和参数一致

public class Txt {
    public static void main(String[] args) {
        filter(Txt::method);
    }
    //静态方法,必须和函数式接口中方法的返回值和参数一致
    public static String method() {
        System.out.println("我是静态方法的函数体");
        return "我是静态方法的返回值";
    }

    public static void filter(Checker ch) {
        System.out.println(ch.checker());
    }
}

interface Checker {
    public  String checker();
}

引用对象方法

​ 与引用静态方法很类似,只是传递方法的时候,需要一个对象的存在

Txt t = new Txt();
filter(t::method);

引用容器中的对象方法

​ 和引用对象方法一样,只是这个对象在容器中

Lambda聚合操作

使用聚合操作遍历数据

import java.util.ArrayList;
import java.util.List;

public class Txt {
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(new Person("张一",35,12000));
        list.add(new Person("张二",85,3000));
        list.add(new Person("张三",15,5600));
        list.add(new Person("张四",71,3400));
        list.add(new Person("张五",55,22200));

        //这个格式其实是一条语句
        list.stream()
                .filter(p -> p.age<60 && p.salary>10000)
                .forEach(p->System.out.println(p));
    }

}

Stream和管道的概念

​ Stream 和Collection结构化的数据不一样,Stream是一系列的元素,像生产线上的罐头一样,一串串的出来。

​ 管道指的是一系列的聚合操作。

​ 管道又分3个部分

​ 管道源:在这个例子里,源是一个List

​ 中间操作: 每个中间操作,又会返回一个Stream,比如.filter()又返回一个Stream, 中间操作是“懒”操 作,并不会真正进行遍历。

​ 结束操作:当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。 结束操作不会返回Stream,但是会返回int、float、String、 Collection或者像forEach,什 么都不返回, 结束操作才进行真正的遍历行为,在遍历的时候,才会去进行中间操作的相关判断

管道源

//把Collection切换成管道源很简单,调用stream()就行了。
list.stream();
//但是数组却没有stream()方法,需要使用
Arrays.stream(array);
//或者
Stream.of(array);

中间操作

​ 对元素进行筛选:
​ filter 匹配
​ distinct 去除重复(根据equals判断)
​ sorted 自然排序
​ sorted(Comparator) 指定排序
​ limit 保留
​ skip 忽略
​ 转换为其他形式的流
​ mapToDouble 转换为double的流
​ map 转换为任意类型的流

结束操作

​ 常见结束操作如下:
​ forEach() 遍历每个元素
​ toArray() 转换为数组
​ min(Comparator) 取最小的元素
​ max(Comparator) 取最大的元素
​ count() 总数
​ findFirst() 第一个元素

## 练习

1)练习-聚合操作

​ 首选准备10个Person对象,age和salary都是随机数。分别用传统方式和聚合操作的方式,把salary第三高的人名称打印出来

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class Txt {
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(new Person("名字"+i,(int)(Math.random()*100),(int)(Math.random()*7000+3000)));
        }
        List<Person> list1 = new ArrayList<>(list);//复制集合
        //使用传统方式,找出薪水第三高的人
        list.sort(new Comparator<Person>() {
            @Override
            public int compare(Person p1, Person p2) {
                if(p1.salary>p2.salary) {
                    return -1;
                }else {
                    return 0;
                }
            }
        });
        System.out.println("传统方式:"+list.get(2));
        //使用聚合方式,找出薪水第三高的人
        Person p = list1.stream()
                .sorted((p1,p2)->p1.salary>p2.salary?-1:1)//排序列表
                .skip(2)//忽略前两个
                .findFirst()//找出第一个
                .get();//获取第一个的对象
        System.out.println("聚合方式:"+p);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值