Lambda表达式、Stream流—————面试必备

Lambda表达式

JDK8的新特性
1、Lambda表达式(函数式编程)
2、Stream流(Lambda的实际运行之一)

函数式编程思想概述

函数有输入量,计算过程,输出量(y=xx+2x+2),函数式编程思想,以一种尽量简单的格式,简化面向对象中复杂的格式,面向对象强调的是以何种形式去做,而函数式编程思想强调的是拿什么东西做什么事情,而不强调以何种形式去做。

冗余的Runnable代码体验

public class TestRunnableDemo {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.printf(Thread.currentThread().getName());
            }
        }).start();
        //分析:传统的Runnable实现方式冗余代码
        //1、为了避免创建新类 我们不得不去搞一个匿名内部类
        //2、为了迎合面向对象语法,我们只能用Runnable的实现类
        //3、重写时,方法必须和接口中的一模一样
        //4、我们真正需要的就是一句任务代码【System.out.printf(Thread.currentThread().getName());】
    }
}

函数式编程Lambda

public class TestRunnableDemo {
    public static void main(String[] args) {
        //体验Lambda表达式写法
        new Thread(()->{ System.out.printf(Thread.currentThread().getName());}).start();
    }
}

Lambda格式

标准格式

(参数列表)->{方法体;retunrn 返回值;}
(参数列表)相当于方法的参数,如果没有参数,那么只写小括号即可。
->:固定用法,代码拿着前面的参数,去做什么事情。
{}:大括号先写计算过程,如果有返回值return 返回值,如果没有返回值return可以省略。

带参数的和返回值的

代码实现:

public class CompareTest {
    public static void main(String[] args) {
        //比较器
        Integer[] nums = {4, 5, 2, 1, 8, 9, 6};
        //对数组排序
        //Arrays.sort(nums);升序
        //降序 使用比较器
        //Arrays.sort(nums, new Comparator<Integer>() {
        //    @Override
        //    public int compare(Integer o1, Integer o2) {
        //        return o2 - o1;
        //    }
        //});
        //打印数组
        //System.out.println(Arrays.toString(nums));
        //使用表达式改写
        Arrays.sort(nums,(Integer o1,Integer o2)->{return o2-o1;});
    }
}

省略格式

1、参数类型可以省略
2、如果参数只有一个,那么小括号可以省略
3、如果大括号中的代码可以写成一句代码,【那么大括号,return关键字和分号可以同时省略】
代码实现一:

 		//体验Lambda表达式写法
        new Thread(()->{ System.out.printf(Thread.currentThread().getName());}).start();
        //省略格式
        new Thread(()-> System.out.printf(Thread.currentThread().getName())).start();

代码实现二:

 		//使用表达式改写
        Arrays.sort(nums, (Integer o1, Integer o2) -> {
            return o2 - o1;
        });
        //省略格式
        Arrays.sort(nums, (o1, o2) -> o2 - o1);
    }

Lambda的前提条件

1、Lambda只能用于替换,有且仅有一个抽象方法的接口和匿名内部类对象,这种接口称为函数式接口
2、Lambda具有上下文推断的功能,所以我们才会出现Lambda的省略格式。

Stream流

传统的循环遍历的弊端

Lambda注重于做什么,而传统的面向对象注重于怎么做。为了解决这种复杂形式,引入了Stream流式思想。

Stream示例

public class StreamTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("赵四");
        list.add("刘三");
        list.add("赵敏");
        //选出以赵开头的名字
        list.stream().filter(s -> s.startsWith("赵"));
        //选出名字为两个字的名字
        list.stream().filter(s -> s.startsWith("赵")).filter(s -> s.length() == 2).forEach(s -> System.out.println(s));
    }
}

获取流的方式

Collection集合获取流

Stream <E> stream=集合对象.stream();

Map集合不能直接获取流,但是可以间接获取流

map.keySet().stream();//获取map的键流
map.values().stream();//获取map的值流
map.entrySet().stream();//获取键值对的流

数组获取流

Stream<数据类型> s=Stream.of(数据类型...变量名)

Stream流中的常用方法

1、foreach逐一处理

//1、获取一个流
        Stream<String> stream = Stream.of("jack", "jkl", "sda");
        //foreach逐一处理
        stream.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        //stream.forEach(stream -> System.out.println(stream));

2、count统计个数

 //2、统计个数
        long count = stream.count();
        System.out.println(count);

3、filter过滤

 //3、filter过滤
        Stream<String> stream1 = stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {//会自动将流中的元素传入
                //我们只想要长度大于3的字符串,返回的依旧是流
                //if (s.length() > 3) {
                //    return true;
                //}

                return s.length() > 3;
            }
        });
        //省略形式,使用Lambda
        Stream<String> stream2 = stream.filter(s -> s.length() > 3);

4、limit取用前几个

 //4、limit,限制,取前几个
        Stream<String> limit = stream.limit(3);
        limit.forEach(s -> System.out.println(limit));//打印一下

5、skip跳过前几个

 //5、skip,跳过前几个
        Stream<String> skip = stream.skip(2);
        skip.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        //System.out.println(skip);
       // skip.forEach(s -> System.out.println(s));
    }

6、map映射
是将流中每个元素,经过某种算法,变成另外一个元素
7、concat组合
静态方法:public staticStream concat(Stream s1,Stream s2)

 //7、组合
        Stream<String> stream2 = Stream.of("rte");
        Stream<String> concat = Stream.concat(stream, stream2);
        concat.forEach(s -> System.out.println(s));
    }

注意:
如果是两个以上的流的合并,需要两两合并。
如果两个流的泛型不一致也可以合并,合并后的新流的泛型是他们的父类,或者是object

总结,函数拼接和终结方法

函数拼接方法:由于这种方法返回的还是流对象,所以支持链式编程
调用该方法后,返回的还是一个流对象。有 filter、limit、skip、map、concat
终结方法:由于终结方法没有返回值,所以不支持链式编程。有forEach,count

Stream综合案例

收集Stream结果

收集到集合中

调用collect()方法即可
代码实现:

 Stream<String> stream2 = Stream.of("rte","黄");
        List<String> collect = stream2.collect(Collectors.toList());
        System.out.println(collect);

收集到数组中

流的toArray()方法
代码实现:

Stream<String> stream2 = Stream.of("rte","黄");
        Object[] array = stream2.toArray();
        System.out.println(array);

注意:
一个流只能收集一次
如果收集到数组中,默认收集到Object数组

感悟

长风破浪会有时,直挂云帆济沧海!

发布了34 篇原创文章 · 获赞 9 · 访问量 1285

猜你喜欢

转载自blog.csdn.net/weixin_43616750/article/details/104960054
今日推荐