14,JAVA8Lambda表达式与Stream流

文章详细介绍了Java8中的Lambda表达式和Stream流的概念与用法。Lambda表达式简化了匿名内部类的使用,提供了简洁的语法来定义函数式接口的实现。Stream流是用于处理集合的新特性,支持链式操作,包括过滤、映射、排序等操作,且不会改变原始数据源。文章通过实例展示了Lambda和Stream在实际编程中的应用。
摘要由CSDN通过智能技术生成

Java8:Lambda表达式与Stream流

1、Lambda表达式

1.1 概述

​ 我理解的lambda表达式,即是一种对于匿名内部方法的简易表示方法。


2.2 具体表述

​ 例如如下代码,若想使用Runnable接口下的run方法
原始方法:先通过创建一个新的类implements去Runnable接口,再用新类的对象调用run方法。

class A implements Runnable{
            @Override
            public void run() {
                System.out.println("原始方法");
            }
        }
        A a = new A();
        a.run();

进阶:我们知道,可以用匿名内部类的方法,将这两个步骤合二为一,进行一定的简化

Runnable r1 = new Runnable(){
            @Override
            public void run() {
                System.out.println("匿名内部类方法");
            }
        };
        r1.run();

最终:但以上的代码过于复杂,使用Lambda表达式替代:

(1)无参情况
 Runnable r2 = () -> System.out.println("test2 is running");
 //函数式接口,要求接口中只有一个方法

“()”括号内,书写该方法的参数(此处为无参方法),表示输入

“ -> ” 箭头,表示在这个重写的接口方法中,具体要做什么
​ 例如此处含义为:什么也不输入,输出"test2 is running"

(2)有参情况

​ 例如Comparator接口中的compare方法,如果我们想比较o1、o2两个数字的大小,则可以将两个数字传入进去。匿名内部类的写法如下:

Comparator<Integer> com1 = new Comparator<>(){
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);
            }
        };
        System.out.println(com1.compare(12,21));

lambda表达式的等效替代:

//lambda:省去不需要的部分,理解的话,相当于传入(o1,o2),箭头就是 return
Comparator<Integer> com2 = (o1, o2) -> Integer.compare(o1,o2);
System.out.println(com2.compare(32,21));

​ 例如,此处的含义为,Comparator接口的对象com2,其内部方法compare,输入o1、o2,其方法return出这两个数的比较结果,即,调用compare方法。

(3) 函数化编程
/**
* 加减乘除
*/
public class Java8Tester {
    public static void main(String args[]){
        Java8Tester tester = new Java8Tester();

//        MathOperation mathOperation = new MathOperation() {
//            @Override
//            public int operation(int a, int b) {
//                return a + b;
//            }
//        };

        // 类型声明
        MathOperation addition = (int a, int b) -> a + b;

        // 不用类型声明
        MathOperation subtraction = (a, b) -> a - b;

        // 大括号中的返回语句
        MathOperation multiplication = (int a, int b) -> { return a * b; };

        // 没有大括号及返回语句
        MathOperation division = (int a, int b) -> a / b;

        System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
        System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
        System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
        System.out.println("10 / 5 = " + tester.operate(10, 5, division));

        // 不用括号
        GreetingService greetService1 = message ->
                System.out.println("Hello " + message);

        // 用括号
        GreetingService greetService2 = (message) ->
                System.out.println("Hello " + message);

        greetService1.sayMessage("Runoob");
        greetService2.sayMessage("Google");
    }

    interface MathOperation {
        int operation(int a, int b);
    }


	//对于operate方法,输入的MathOperation对象调用其重写的方法operation
	//如果正常情况下,则需要分别新建4个不同的类,实现MathOperation接口的方法,再创建四个对象进行加减乘除。
	//使用Labmda表达式就简单多了
    private int operate(int a, int b, MathOperation mathOperation){
        return mathOperation.operation(a, b);
    }
}

2、Stream流

2.1 概念

​ Stream就是来操作容器(Collection)的,比如List,或者数组,等。其具有以下性质:

  • 1.Stream,是对数据运算,与cpu工作。
  • 2.Stream不会自己储存元素,不会改变源对象,操作有延迟。
  • 3.流程: Stream实例化 ->中间操作->终止操作
  • 注意:终止操作以后不能直接返回中间操作
  • 过滤条件:截断与跳过,筛选去重,函数映射,排序

2.2 如何将容器、数组等,转化为Stream流

(1)对于数组

​ 用Arrays.stream(数组对象) 、或者Stream.of(数组内元素)

方法1:
 int arr[] = new int[]{1,2,3,4,5};
 IntStream stream = Arrays.stream(arr);
 
方法2:
 Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);
(2)对于容器

​ 采用“对象.stream()”方法

List<Integer> list = Arrays.asList(11,333,5555,7,9,88,1000,442424);
list.stream().sorted().forEach(System.out::println);

2.3 过滤条件:Stream流的API

例子1:数组+对象

Employee name1 = new Employee("name1", 111);
Employee name2 = new Employee("name2", 222);
Employee name3 = new Employee("name3", 333);
Employee arr1[] = new Employee[]{name1,name2,name3};
Stream<Employee> stream1 = Arrays.stream(arr1);
(1)过滤流 filter

​ (输入一个对象,名字任意,这个对象就是stream流里的对象。 返回的就是需要筛选的条件)

stream1.filter(employee -> employee.getAge() > 300).forEach(System.out::println);
(2)截断流 limit(n)

​ 使元素不超过给定量n

Arrays.stream(arr1).limit(2).forEach(System.out::println);
(3)跳过元素 skip(n)

​ 返回了一个流,这个流扔掉了前n个元素。元素不足会返回空

Arrays.stream(arr1).skip(1).forEach(System.out::println);
(4)哈希筛选 distinct()

​ 通过流的元素的 hasCode()和equals() 来去除 重复 元素

list.stream().distinct().forEach(System.out::println);

例子2:List

List<String> list = Arrays.asList("AA", "BB", "CC", "DD", "EE");
(5)⭐映射map()

​ 传入的容器的每个对象(关键,每个),随便起个名 —> 要对他做的函数

​ 比如,想对list进行全部元素的“小写化”

list.stream().map(str -> str.toLowerCase()).forEach(System.out::println);

​ 注意:map内的匿名内部函数,其实都是有return返回值的。如果仅仅是进行类似Set方法这类方法,想进行赋值的话,要将实体类前加上:
@Accessors(chain = true) 注解//执行完set方法后会return对象

(6)映射flatmap()

与map相比,flatmap能够将数组内的数组自动拆分为单个元素

list.stream().flatMap(StreamApi_::fromStringToStream).forEach(System.out::println);
(7)排序sorted()
//普通排序
List<Integer> list = Arrays.asList(11,333,5555,7,9,88,1000,442424);
list.stream().sorted().forEach(System.out::println);
//定制排序(按照对象的age)
        List<Employee> listemp = new ArrayList<>();
        listemp.add(new Employee("name1", 111));
        listemp.add(new Employee("name5", 555));
        listemp.add(new Employee("name2", 222));
        listemp.add(new Employee("name3", 333));
        //凡是排序都用到compare与comparable,输入两个参数。记住,compare是集合类的方法
        listemp.stream().sorted((e1,e2)-> Integer.compare(e1.getAge(),e2.getAge())).forEach(System.out::println);

2.4 终止Api:匹配与查找

(1)匹配:返回布尔

​ 即,匹配成功or失败。

List<Employee> listemp = new ArrayList<>();
listemp.add(new Employee("name1", 111));
listemp.add(new Employee("bame5", 555));
listemp.add(new Employee("came2", 222));
listemp.add(new Employee("dame3", 333));
//1.allMatch,判断全部是否满足
boolean allMatch = listemp.stream().allMatch(employee -> employee.getAge() > 100);
        System.out.println(allMatch);
//2.anyMatch,判断是否存在一个
boolean anyMatch = listemp.stream().anyMatch(employee -> employee.getAge() > 500);
        System.out.println(anyMatch);
//3.noneMatch,检查是否“没有”匹配的元素(没有则返回true)
boolean noneMatch = listemp.stream().noneMatch(employee -> employee.getName().startsWith("e"));
        System.out.println(noneMatch);
//还有findFirst,findAny,count(返回匹配条件下的数目),max,min(要搭配compare
(2)归约reduce
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
Integer sum = list.stream().reduce(0, Integer::sum);//三个参数,初始值,第一个和第二个输入。
(3)收集数据collect

​ 当我们对 Stream 流中的数据操作完成之后,如果需要将流的结果进行保存,方便我们接下来对结果的继续操作,该怎么办呢?

​ Stream 流提供了一个 collect() 方法,可以收集流中的数据到【集合】或者【数组】中去。

/**
 * 收集Stream流中的数据到集合中
 * 备注:切记Stream流只能被消费一次,流就失效了
 * 如下只是示例代码
 */
public class CollectDataToCollection{
 
    public static void main(String[] args) {
        //Stream 流
        Stream<String> stream = Stream.of("aaa", "bbb", "ccc", "bbb");
        //收集流中的数据到集合中
        //1.收集流中的数据到 list
        List<String> list = stream.collect(Collectors.toList());
        System.out.println(list);
 
        //2.收集流中的数据到 set
        Set<String> collect = stream.collect(Collectors.toSet());
        System.out.println(collect);
 
        //3.收集流中的数据(ArrayList)(不收集到list,set等集合中,而是)收集到指定的集合中
        ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
        System.out.println(arrayList);
 
        //4.收集流中的数据到 HashSet
        HashSet<String> hashSet = stream.collect(Collectors.toCollection(HashSet::new));
        System.out.println(hashSet);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好奇的7号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值