一、基本介绍二、Lambda表达式
1、优点2、基本格式3、进一步优化 三、方法引用四、Stream流
1、简介2、准备案例3、创建流 *** 作4、中间 *** 作(过滤、排序、去重、转换等等)
(1)、filter(2)、distinct(3)、map(4)、sorted(5)、limit(6)、skip(7)、flatmap 5、终结 *** 作
(1)、forEach(2)、count(3)、min&max(4)、collect(5)、anyMatch(6)、allMatch(7)、noneMatch(8)、findAny(9)、findFirst(10)、reduce 6、基本数据类型转化优化7、Stream流总结 四、Optional
1、作用2、使用Optional避免空指针异常3、有关Optional
一、基本介绍"函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论。
它属于"结构化编程"的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。
函数式编程优点:
代码简介开发迅速接近自然语言,易于理解易于并发编程 二、Lambda表达式 1、优点
不关注对象是什么,不关注方法名是什么,只关注如何 *** 作数据
可推导可省略
对匿名内部类(是接口且仅有一个抽象方法)进行简化
(参数列表)->{代码}
例1:
new Thread(new Runnable() { @Override public void run() { System.out.println("Lambda表达式学习"); } }).start(); new Thread(() -> { System.out.println("Lambda表达式学习"); }).start();
例2:
@FunctionalInterface public interface IntBinaryOperator { int applyAsInt(int left, int right); } public static int calculateNum(IntBinaryOperator operator) { int a = 20; int b = 10; return operator.applyAsInt(a, b); } int i = calculateNum(new IntBinaryOperator() { @Override public int applyAsInt(int left, int right) { return left + right; } }); int i = calculateNum((left, right) -> { return left + right; });
例3:
@FunctionalInterface public interface IntPredicate { boolean test(int value); } 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); } } } printNum(new IntPredicate() { @Override public boolean test(int value) { return value % 2 == 0; } }); printNum((value)->{ return value%2==0; });3、进一步优化
参数类型可以省略(上述例子全部省略)方体体只有一句代码时,大括号、return、分号可以省略例如:
如例3 可写为: printNum((value) -> value % 2 == 0);方法体只有一个参数时小括号也可以省略
再改写:printNum(value -> value % 2 == 0);
三、方法引用
lambda表达式再一次改进
基本格式:
类名或对象名::方法名
什么时候用?
我也不太懂 只会alter+enter
例: .mapToInt(author -> author.getAge())
改进:.mapToInt(Author::getAge)
优点:更加简便的 *** 作集合和对象
2、准备案例@Data @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode public class Author{ private Long id; private String name; private int age; private List3、创建流 *** 作books; public Integer getHHH(int age,String name){ return Integer.valueOf(age+name); } } @Data @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode public class Book { private Long id; private String title; private String category; private double price; } private static List getAuthors() { Book book = new Book(1L, "JavaSE", "JAVA", 200); Book book1 = new Book(2L, "Python精通", "Python", 205); Book book2 = new Book(3L, "JAVAEE", "JAVA", 28); Book book3 = new Book(4L, "C++Prime", "C++", 2254); Book book4 = new Book(5L, "JAVAWeb", "JAVA,Web", 445); Book book5 = new Book(6L, "Redis", "database,Linux", 54); Book book6 = new Book(7L, "Mysql", "database", 545); List list = new ArrayList<>(); List list1 = new ArrayList<>(); List list2 = new ArrayList<>(); list.add(book); list.add(book1); list.add(book2); list.add(book2); list1.add(book3); list1.add(book4); list2.add(book6); list2.add(book6); list2.add(book5); Author author = new Author(1L, "Mae", 21, list); Author author1 = new Author(2L, "Strive", 25, list1); Author author2 = new Author(3L, "Naomi", 28, list2); Author author3 = new Author(3L, "Naomi", 28, list2); return new ArrayList<>(Arrays.asList(author, author1, author2, author3)); }
单列集合:集合对象.stream()
//例: List authorList=getAuthorList(); authorList.stream();
多列集合:map.entrySet.stream();
//例: Mapmap=new HashMap<>(); map.entrySet.stream();
数组:Arrays.stream(数组名)
4、中间 *** 作(过滤、排序、去重、转换等等) (1)、filter过滤 *** 作
例:输出年龄大于25的作家
List authors = getAuthors(); authors.stream() .filter(author -> author.getAge()>25) .forEach(author -> System.out.println(author));
过滤后只剩下两条
去重
案例:打印年龄超过25的作家 并且去重
List authors = getAuthors(); authors.stream() .filter(author -> author.getAge()>25) .distinct() .forEach(author -> System.out.println(author));
对流中的元素进行计算或转换(类型)
例:将对象按照年龄转成Integer 然后将年龄加10
List authors = getAuthors(); authors.stream() .map(author -> author.getAge()) .distinct() .map(age -> age + 10) .forEach(age -> System.out.println(age));
排序
例:按照年龄降序
List authors = getAuthors(); authors.stream() .map(author -> author.getAge()) .distinct() .sorted((o1, o2) -> o2-o1) .forEach(age -> System.out.println(age));
限制流的最大长度
案例:打印年龄最大的两个作家(需去重和排序)
List authors = getAuthors(); authors.stream() .distinct() .limit(2) .forEach(author -> System.out.println(author));
跳过所定义长度的流
案例:打印除了最大年龄的所有作家
List authors = getAuthors(); authors.stream() .distinct() .sorted((o1, o2) -> o2.getAge() - o1.getAge()) .skip(1) .forEach(author -> System.out.println(author));
将一个对象转换成多个对象
例 打印所有书籍名字 并去除
List authors = getAuthors(); authors.stream() .flatMap(author -> author.getBooks().stream()) .distinct() .forEach(book -> System.out.println(book ));
使用 flatmap 将一个作家集合转换成多个书本集合
例 打印所有书本分类 并去重(注意属于多个分类的书籍)
List authors = getAuthors(); authors.stream() .flatMap(author -> author.getBooks().stream()) .distinct() .flatMap(book -> Arrays.stream(book.getCategory().split(","))) .distinct() .forEach(s -> System.out.println(s));
关键:将属于多个分类的书籍 用逗号分隔转换成数组,然后再用数组的stream()方法 转化成流
终结 *** 作是stream流中必须的,如果没有终结 *** 作,那么中间 *** 作将不会执行
(1)、forEach对流中的元素进行遍历
前面的案例都用forEach作为终结 *** 作
获取流中元素个数
例:获取书本个数(去重)
获取流中元素的最小值和最大值
例:获取年龄最大的作者
把当前流转换成一个集合
案例 转成成set集合 键为作者,值为书名
List authors = getAuthors(); Map> map = authors.stream() .distinct() .collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks())); System.out.println(map);
判断是否有符合匹配条件的元素
例:判断是否有年龄大于25的作家
List authors = getAuthors(); boolean b = authors.stream() .anyMatch(author -> author.getAge() > 25);
判断所有元素是否都符合条件
(7)、noneMatch判断是否都不符合条件
(8)、findAny找到任意一个符合条件的元素
(9)、findFirst找到第一个符合条件的元素
(10)、reduce对流中的数据按照指定规则方式计算出一个结果
例 求作者年龄之和(去重)
List authors = getAuthors(); Integer sum = authors.stream() .distinct() .map(author -> author.getAge()) .reduce(0, (result, age) -> (result + age)); System.out.println(sum);
不使用map,而使用mapToInt/Double/Long、flatMapToInt/Double/Long
List authors = getAuthors(); authors.stream() .mapToInt(author -> author.getAge()) .forEach(value -> System.out.println(value));7、Stream流总结
流是惰性求值,即不进行终结 *** 作,中间 *** 作也不会执行流是一次性的,对一个集合创建了流,不能再对其进行第二次创流不影响原数据 四、Optional 1、作用
主要为了避免开发过程中出现空指针异常
空指针确实很烦
Exception in thread "main" java.lang.NullPointerException
使用ofNullable获取对象(无论是否为空)
使用ifPresent 如果不为空则执行 为空则不会执行
List authors = getAuthors(); Optional3、有关OptionalauthorListOptional = Optional.ofNullable(authors); authorListOptional.ifPresent(authors1 -> System.out.println(authors1));
Optional中还有许多方法与Stream流中类似
不演示了
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)