Lambda表达式

:::tips

Lambda表达式的标准格式

  • 组成Lambda表达式的三要素:形参列表,箭头,代码块。

Lambda表达式的省略格式

  • 参数类型可以省略
    • 比如(Integer o1, Integer o2) 省略后 (o1, o2)
  • 如果参数有且仅有一个,参数类型和小括号都可以省略
    • 比如(String s) 省略后 s
  • 如果代码块的语句只有一条,可以省略大括号,分号和return。

Lambda表达式的前提

  • 方法的参数是接口
  • 接口中只能有一个抽象方法

说明

  • 有且只有一个抽象方法的接口,也叫函数式接口
  • 可以在接口上加 @FunctionalInterface 注解进行标记 :::

方法引用

:::tips

概述

  • 方法引用是java8的新特性之一, 可以直接引用已有Java类或对象的方法或构造器
  • 方法引用与Lambda表达式结合使用,可以进一步简化代码

方法引用格式

  • 对象名 :: 成员方法
  • 类名 :: 静态方法
  • 类名 :: new

方法引用使用前提

  • Lambda表达式中仅仅调用了一个方法
  • 调用的方法与要实现的抽象方法的参数和返回值一致时,可以使用方法引用代替 :::

Stream

:::tips

概述:

  • 从JDK8开始,得益于Lambda所带来的函数式编程,引入了一个全新的Stream概念,用于简化已有集合类的数据操作

创建Stream流的方式

  • 根据集合获取流
    • Collection根接口中提供了 stream( ) 方法可以获取流
    • 单列集合:直接调用stream()方法即可
    • 双列集合:先获取键和值的单列集合,再通过集合获取键和值各自的Stream流。
  • 根据of方法获取流
    • Stream类提供了静态的 of( ) 方法,可以创建一个流对象
    • Stream.of(T … values)

使用注意

  • 一个Stream流对象只能操作一次
  • 调用中间方法会返回新流,以便下次操作使用
  • 终结方法如果没调用,中间方法也不会执行 :::

Stream流的常用方法

成员方法 方法作用 返回值类型 方法种类
filter 过滤 Stream 中间方法
limit 取用前几个 Stream 中间方法
skip 跳过前几个 Stream 中间方法
map 映射 Stream 中间方法
count 统计个数 long 终结方法
forEach 逐一处理 void 终结方法
静态方法 方法作用 返回值类型 方法种类
static concat(流1,流2) 组合两个流 Stream 静态方法

Stream流的收集

:::tips

概述

  • 对Stream流操作完成之后,可以将流中的最终结果进行收集,存储到集合或数组中

Stream流收集到数组

  • 方法:
    • Object[] toArray();
  • 用法:
    • Stream st = Stream.of(“11”, “22”, “33”);
    • Object[] arr = st.toArray(); :::
  1. /*
  2. 根据集合对象获取流
  3. 单列集合:集合对象.stream()
  4. 双列集合:先获取键的集合,在通过键的集合获取流
  5. 根据of方法获取流
  6. Static <T> Stream <T> of(T...values)
  7. */
  8. public class DemoStream {
  9. public static void main(String[] args) {
  10. ArrayList<String> list = new ArrayList<>();
  11. Collections.addAll(list, "令狐冲", "风清扬");
  12. //通过集合获取流
  13. Stream<String> stream = list.stream();
  14. //根据of方法获取流
  15. Stream<String> s1 = Stream.of("令狐冲", "风清扬");
  16. Stream<Integer> s2 = Stream.of(1, 2, 3, 4);
  17. Stream<Double> s3 = Stream.of(1.1, 2.2, 3.3);
  18. }
  19. }
public static void main(String[] args) {
    //创建流
    Stream<Integer> stream = Stream.of(11, 22, 33, 44, 55);
    //遍历流中的数据
    //匿名内部类
    /*stream.forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer a) {
                System.out.println(a);
            }
        });*/
    //Lambda简化
    //stream.forEach((Integer a) -> {System.out.println(a);});

    //stream.forEach(a -> System.out.println(a));
    //使用方法引用
    //抽象的accept方法,实现的代码就是单纯的引用了println方法
    stream.forEach(System.out::println);
}
public static void main(String[] args) {
    //筛选出偶数集合
    Stream<Integer> stream = Stream.of(11, 22, 33, 44, 55, 66);
    //筛选出偶数
    /*Stream<Integer> stream1 = stream.filter(new Predicate<Integer>() {
            @Overrid
            //返回值为true,元素存入新的流
            //返回值为false,元素删除
            public boolean test(Integer a) {
                return a % 2 == 0;
            }
        });
        stream1.forEach(System.out::println);*/

    stream.filter(a -> a % 2 == 0).forEach(System.out::println);
}
public static void main(String[] args) {
    Stream<Integer> stream = Stream.of(11, 22, 33, 44, 55, 66);
    //获取前三个
    stream.limit(3).forEach(System.out::println);
}

public static void main(String[] args) {
    Stream<Integer> stream = Stream.of(11, 22, 33, 44, 55, 66);
    //获取前四个跳过前两个
    stream.limit(4).skip(2).forEach(System.out::println);
}
 public static void main(String[] args) {
     //将流中的数据转换为整数类型,并筛选出奇数遍历
     Stream<String> stream = Stream.of("11", "22", "33", "44", "55", "66");
     //将流中的数据转换为整数类型
     //Function<流元素的原类型, 要转换的新类型>
     /*stream.map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                //Integer类的parseInt方法就是apply方法要做的事情
                return Integer.parseInt(s);
            }
        });*/
     //stream.map(s -> Integer.parseInt(s));
     //静态方法的引用, 类名::静态方法名
     //stream.map(Integer::parseInt);
     stream.map(Integer::parseInt)
         //并筛选出奇数
         .filter(a -> a % 2 != 0)
         //遍历输出
         .forEach(System.out::println);
    }
}
/*
    已知两个集合数据:
        第一个队伍数据:"令狐冲", "风清扬", "任我行", "东方不败", "岳不群"  of()
        第二个队伍数据:"马云", "李彦宏", "刘强东", "马化腾", "马保国"  of()

    要求:
        第一个队伍只要名字为3个字的姓名。 filter
        第一个队伍筛选之后只要前3人。limit(3)

        第二个队伍只要姓马的姓名。 filter
        第二个队伍不要前2人。 skip(2)

        将两个队伍合并到一个队伍  concat(流1, 流1)
        根据姓名创建Person对象, map
        存储到一个新集合。 collect(Collectors.toList())
        遍历集合 forEach

     使用Stream流式编程完成
 */
public class Demo1 {
    public static void main(String[] args) {
        //Stream<String> stream1 = Stream.of("令狐冲", "风清扬", "任我行", "东方不败", "岳不群");
        //Stream<String> stream2 = Stream.of("马云", "李彦宏", "刘强东", "马化腾", "马保国");

        //Stream<String> s1 = stream1.filter(s -> s.length() == 3).limit(3);
        //Stream<String> s2 = stream2.filter(s -> s.contains("马")).skip(2);

        Stream.concat(
                Stream.of("令狐冲", "风清扬", "任我行", "东方不败", "岳不群")
                        .filter(s -> s.length() == 3)
                        .limit(3),
                Stream.of("马云", "李彦宏", "刘强东", "马化腾", "马保国")
                        .filter(s -> s.startsWith("马"))
                        .skip(2)
        )
                .map(Person::new)
                .collect(Collectors.toList())
                .forEach(System.out::println);
    }
}

public class Person{
    private String name;
    //构造方法 setget toSting方法
}