1. 概述

1.1 为什么学?

  • 能够看懂公司里的代码

  • 大数量下处理集合效率高

  • 代码可读性高

  • 消灭嵌套地狱

//查询未成年作家的评分在70以上的书籍 由于洋流影响所以作家和书籍可能出现重复,需要进行去重
List<Book> bookList = new ArrayList<>();
Set<Book> uniqueBookValues = new HashSet<>();
Set<Author> uniqueAuthorValues = new HashSet<>();
for (Author author : authors) {if (uniqueAuthorValues.add(author)) {if (author.getAge() < 18) {List<Book> books = author.getBooks();for (Book book : books) {if (book.getScore() > 70) {if (uniqueBookValues.add(book)) {bookList.add(book);}}}}}
}
System.out.println(bookList);
List<Book> collect = authors.stream().distinct().filter(author -> author.getAge() < 18).map(author -> author.getBooks()).flatMap(Collection::stream).filter(book -> book.getScore() > 70).distinct().collect(Collectors.toList());
System.out.println(collect);

1.2 函数式编程思想

1.2.1 概念

面向对象思想需要关注用什么对象完成什么事情。而函数式编程思想就类似于我们数学中的函数。它主要关注的是对数据进行了什么操作。

1.2.2 优点

  • 代码简洁,开发快速

  • 接近自然语言,易于理解

  • 易于"并发编程"

2. Lambda表达式

2.1 概述

Lambda是JDK8中一个语法糖。他可以对某些匿名内部类的写法进行简化。它是函数式编程思想的一个重要体现。让我们不用关注是什么对象。而是更关注我们对数据进行了什么操作。

2.2 核心原则

可推导可省略

2. 3 基本格式

(参数列表)->{代码}

例一

我们在创建线程并启动时可以使用匿名内部类的写法:

new Thread(new Runnable() {@Overridepublic void run() {System.out.println("你知道吗 我比你想象的 更想在你身边");}
}).start();

可以使用Lambda的格式对其进行修改。修改后如下:

new Thread(()->{System.out.println("你知道吗 我比你想象的 更想在你身边");
}).start();

例二:

现有方法定义如下,其中IntBinaryOperator是一个接口。先使用匿名内部类的写法调用该方法。

​public static int calculateNum(IntBinaryOperator operator){int a = 10;int b = 20;return operator.applyAsInt(a, b);}
​public static void main(String[] args) {int i = calculateNum(new IntBinaryOperator() {@Overridepublic int applyAsInt(int left, int right) {return left + right;}});System.out.println(i);}

Lambda写法:

    public static void main(String[] args) {int i = calculateNum((int left, int right)->{return left + right;});System.out.println(i);}

例三:

现有方法定义如下,其中IntPredicate是一个接口。先使用匿名内部类的写法调用该方法。

    public static void printNum(IntPredicate predicate){int[] arr = {1,2,3,4,5,6,7,8,9,10};for (int i : arr) {if(predicate.test(i)){System.out.println(i);}}}public static void main(String[] args) {printNum(new IntPredicate() {@Overridepublic boolean test(int value) {return value%2==0;}});}

Lambda写法:

    public static void main(String[] args) {printNum((int value)-> {return value%2==0;});}public static void printNum(IntPredicate predicate){int[] arr = {1,2,3,4,5,6,7,8,9,10};for (int i : arr) {if(predicate.test(i)){System.out.println(i);}}}

例四:

现有方法定义如下,其中Function是一个接口。先使用匿名内部类的写法调用该方法。

    public static <R> R typeConver(Function<String,R> function){String str = "1235";R result = function.apply(str);return result;}public static void main(String[] args) {Integer result = typeConver(new Function<String, Integer>() {@Overridepublic Integer apply(String s) {return Integer.valueOf(s);}});System.out.println(result);}

Lambda写法:

        Integer result = typeConver((String s)->{return Integer.valueOf(s);});System.out.println(result);
​

例五:

现有方法定义如下,其中IntConsumer是一个接口。先使用匿名内部类的写法调用该方法。

    public static void foreachArr(IntConsumer consumer){int[] arr = {1,2,3,4,5,6,7,8,9,10};for (int i : arr) {consumer.accept(i);}}public static void main(String[] args) {foreachArr(new IntConsumer() {@Overridepublic void accept(int value) {System.out.println(value);}});}

Lambda写法:

    public static void main(String[] args) {foreachArr((int value)->{System.out.println(value);});}

2.4 省略规则

  • 参数类型可以省略

  • 方法体只有一句代码时大括号return和唯一一句代码的分号可以省略

  • 方法只有一个参数时小括号可以省略

  • 以上这些规则都记不住也可以省略不记

3. Stream流

3.1 概述

Java8的Stream使用的是函数式编程模式,如同它的名字一样,它可以被用来对集合或数组进行链状流式的操作。可以更方便的让我们对集合或数组操作。

3.2 案例数据准备

   (导入依赖)
<dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version></dependency></dependencies>
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode//用于后期的去重使用
public class Author {//idprivate Long id;//姓名private String name;//年龄private Integer age;//简介private String intro;//作品private List<Book> books;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode//用于后期的去重使用
public class Book {//idprivate Long id;//书名private String name;
​//分类private String category;
​//评分private Integer score;
​//简介private String intro;
​
}
    private static List<Author> getAuthors() {//数据初始化Author author = new Author(1L,"蒙多",33,"一个从菜刀中明悟哲理的祖安人",null);Author author2 = new Author(2L,"亚拉索",15,"狂风也追逐不上他的思考速度",null);Author author3 = new Author(3L,"易",14,"是这个世界在限制他的思维",null);Author author4 = new Author(3L,"易",14,"是这个世界在限制他的思维",null);
​//书籍列表List<Book> books1 = new ArrayList<>();List<Book> books2 = new ArrayList<>();List<Book> books3 = new ArrayList<>();
​books1.add(new Book(1L,"刀的两侧是光明与黑暗","哲学,爱情",88,"用一把刀划分了爱恨"));books1.add(new Book(2L,"一个人不能死在同一把刀下","个人成长,爱情",99,"讲述如何从失败中明悟真理"));
​books2.add(new Book(3L,"那风吹不到的地方","哲学",85,"带你用思维去领略世界的尽头"));books2.add(new Book(3L,"那风吹不到的地方","哲学",85,"带你用思维去领略世界的尽头"));books2.add(new Book(4L,"吹或不吹","爱情,个人传记",56,"一个哲学家的恋爱观注定很难把他所在的时代理解"));
​books3.add(new Book(5L,"你的剑就是我的剑","爱情",56,"无法想象一个武者能对他的伴侣这么的宽容"));books3.add(new Book(6L,"风与剑","个人传记",100,"两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));books3.add(new Book(6L,"风与剑","个人传记",100,"两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));
​author.setBooks(books1);author2.setBooks(books2);author3.setBooks(books3);author4.setBooks(books3);
​List<Author> authorList = new ArrayList<>(Arrays.asList(author,author2,author3,author4));return authorList;}

3.3 快速入门

3.3.1 需求

我们可以调用getAuthors方法获取到作家的集合。现在需要打印所有年龄小于18的作家的名字,并且要注意去重。

3.3.2 实现

        //打印所有年龄小于18的作家的名字,并且要注意去重List<Author> authors = getAuthors();authors.stream()//把集合转换成流.distinct()//先去除重复的作家.filter(author -> author.getAge()<18)//筛选年龄小于18的.forEach(author -> System.out.println(author.getName()));//遍历打印名字

3.4 常用操作

3.4.1 创建流

单列集合: 集合对象.stream()

        List<Author> authors = getAuthors();Stream<Author> stream = authors.stream();

数组:Arrays.stream(数组)或者使用Stream.of来创建

        Integer[] arr = {1,2,3,4,5};Stream<Integer> stream = Arrays.stream(arr);Stream<Integer> stream2 = Stream.of(arr);

双列集合:转换成单列集合后再创建

        Map<String,Integer> map = new HashMap<>();map.put("蜡笔小新",19);map.put("黑子",17);map.put("日向翔阳",16);
​Stream<Map.Entry<String, Integer>> stream = map.entrySet().stream();

3.4.2 中间操作

filter

可以对流中的元素进行条件过滤,符合过滤条件的才能继续留在流中。

例如:

打印所有姓名长度大于1的作家的姓名

        List<Author> authors = getAuthors();authors.stream().filter(author -> author.getName().length()>1).forEach(author -> System.out.println(author.getName()));

map

可以把对流中的元素进行计算或转换。

例如:

打印所有作家的姓名

        List<Author> authors = getAuthors();
​authors.stream().map(author -> author.getName()).forEach(name->System.out.println(name));
//        打印所有作家的姓名List<Author> authors = getAuthors();
​
//        authors.stream()
//                .map(author -> author.getName())
//                .forEach(s -> System.out.println(s));
​authors.stream().map(author -> author.getAge()).map(age->age+10).forEach(age-> System.out.println(age));

distinct

可以去除流中的重复元素。

例如:

打印所有作家的姓名,并且要求其中不能有重复元素。

        List<Author> authors = getAuthors();authors.stream().distinct().forEach(author -> System.out.println(author.getName()));

注意:distinct方法是依赖Object的equals方法来判断是否是相同对象的。所以需要注意重写equals方法。

待更新

函数式编程-Stream流相关推荐

  1. JAVA学习 API_day11(属性集, 函数式编程, stream流)

    属性集, 函数式编程, stream流 I/O流小结 1. 属性集 2. 函数式编程 3. stream流 I/O流小结 文件复制: BufferedInputStream/BufferedOutpu ...

  2. 函数式编程-Stream流(来源三更草堂)

    函数式编程-Stream流 1. 概述 1.1 为什么学? 能够看懂公司里的代码 大数量下处理集合效率高 代码可读性高 消灭嵌套地狱 //查询未成年作家的评分在70以上的书籍 由于洋流影响所以作家和书 ...

  3. 函数式编程-Stream流/lambda表达式/Optional/函数式接口/方法引用/高级用法

    函数式编程-Stream流 不会Lambda表达式.函数式编程?你确定能看懂公司代码?-java8函数式编程(Lambda表达式,Optional,Stream流)从入门到精通-最通俗易懂 1. 概述 ...

  4. Java8函数式编程——Stream流

    函数式编程-Stream流 实例练习:https://javadaily.cn/post/2022020817/7f222b3057fb/ 1. 概述 1.1 为什么学? 能够看懂公司里的代码 大数量 ...

  5. java学习笔记20(Lambda表达式、函数式编程、流式计算、练习)

    文章目录 11.3 学习内容 Lambda表达式 Lambda标准格式 格式说明 省略规则 使用前提 函数式接口 预定义的函数式接口 工作内容 任务1 总结&明日计划 11.4 学习内容 流式 ...

  6. Lambda表达式接口更新方法引用函数式接口Stream流

    Lambda表达式&接口更新&方法引用&函数式接口&Stream流 Lambda 1.程序启动三种不同的表现形式 2.Lambda表达式的标准格式 3.练习 Lambd ...

  7. 【Java】Java函数式编程以及流的操作

    文章目录 大纲 lambda表达式 一般内部类 局部内部类 匿名内部类 基于函数式接口的lambda表达式 JDK8中自带的函数式接口 Predicate判断 Consumer消费 Supplier供 ...

  8. jdk8銝要onematch_JDK 8 新特性之函数式编程 → Stream API

    开心一刻 今天和朋友们去K歌,看着这群年轻人一个个唱的贼嗨,不禁感慨道:年轻真好啊! 想到自己年轻的时候,那也是拿着麦克风不放的人 现在的我没那激情了,只喜欢坐在角落里,默默的听着他们唱,就连旁边的妹 ...

  9. 【CSDN软件工程师能力认证学习精选】 Java8新特性学习-函数式编程(Stream/Function/Optional/Consumer)

    CSDN软件工程师能力认证是由CSDN制定并推出的一个能力认证标准,宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备, ...

最新文章

  1. Linux 下安装matlab2014a
  2. VMware View 5.0 Ready! 资源汇总(持续更新)
  3. 远程监督关系抽取漫谈:结合知识图谱和图神经网络
  4. 英语口语 week13 Monday
  5. Paypal 在线支付接口应用从零开始,第2节,[支付API原理及流程]
  6. mysql 递归查询树型结构_MySQL递归查询所有子节点,树形结构查询
  7. 入门机器学习(九)--应用机器学习的建议
  8. 深度学习制作数据集的部分代码实现(解压zip、生成json文件)
  9. ajax怎样带值,ajax携带状态值
  10. chainmaker 交易执行失败也会打包到区块 落盘
  11. Hello World 我的第一个VB程序
  12. 单元在整体坐标系下的刚度矩阵
  13. pytest文档24-fixture的作用范围(scope)
  14. 温暖和暖和的区别Java_国内冬天哪里比较暖和 冬天暖和的城市排名
  15. 何时需要对时间序列进行Log Transformation
  16. 第一次学游泳技巧_第一次学游泳作文8篇
  17. mysql constant number,Mysql报Too many connections,不要乱用ulimit了,看看如何正确修改进程的最大文件数...
  18. SAM-DETR源码讲解
  19. 跨域(cross-domain)访问 cookie (读取和设置)
  20. 让你分分钟学会qt视频播放器

热门文章

  1. 【js html】对于img图片的引用填充,src可以给什么值?
  2. 华为nova8se和华为nova7pro哪个好-哪个更值得入手-参数对比
  3. 详解CorelDRAW X7的多种视图显示模式
  4. 3000字梳理大数据开发流程及规范(建议收藏)
  5. 中国土地市场网爬虫案例
  6. 阵列信号DOA估计系列(二).导向矢量与空间FFT(附代码)
  7. 开源免费Webrtc转发服务器Mediasoup的概念解释与基本介绍(一)
  8. Redis 3.0集群搭建/配置/FAQ
  9. 基于php鲜花花卉销售商城网站(源码+系统+mysql数据库+Lw文档)
  10. 前端提效 - js 批量导出 excel 为zip压缩包