接口中默认方法修饰为普通方法

JDK8之前

  • 变量:public static fianl修饰
  • 方法:public abstract

JDK8开始

  • 支持使用staticdefault修饰,二者都可以写方法体,可以不要求子类重写

  • 普通方法可以有方法体

  • 抽象方法没有方法体,需要子类实现

Lambda表达式

使用Lambda表达式依赖于函数接口

  1. 在接口中只能有一个抽象方法

  2. 在函数接口中定义Object类中的方法

  3. 使用默认或者静态方法

  4. @FunctionalInterface 标识该接口为函数接口,如:

    1/**
    2 * 只有一个抽象方法
    3 * 函数接口
    4 */
    5public interface MyFunctionalInterface {
    6  void get();
    7}
    

    如果在该接口上加上注解@FunctionalInterface,则该接口为中不能再有其他抽象方法,否则报错。若是有多个抽象方法,则使用Lambda表达式的时候无法知道调用哪一个方法

  5. @FunctionalInterface标识的类中可以有default方法或者Object类中的方法,如:

    1@FunctionalInterface
    2public interface MyFunctionalInterface {
    3  void get();
    4
    5  default void add(){
    6  }
    7
    8  String toString();
    9}
    

Lambda表达式语法

  • () 参数列表
  • -> 分割
  • {} 方法体
  • 完整: (a, b) -> {}

无参方法调用

 1@FunctionalInterface
 2public interface WuCanInterface {
 3  void get();
 4}
 5
 6public class Test01 {
 7  public static void main(String[] args) {
 8    // 匿名内部类
 9    new WuCanInterface() {
10      @Override
11      public void get() {
12        System.out.println("get");
13      }
14    }.get();
15
16    // Lambda表达式
17    WuCanInterface wuCanInterface = () -> {
18      System.out.println("lambda get");
19    };
20    wuCanInterface.get();
21      
22    // 精简Lambda表达式
23    // 方法体中只有一条 语句的时候,不需要写{}
24	((WuCanInterface)() -> System.out.println("精简 lambda表达式")).get();
25  }
26}

有参方法调用

 1@FunctionalInterface
 2public interface YouCanInterface {
 3  String get(int i, int j);
 4}
 5
 6public class Test02 {
 7  public static void main(String[] args) {
 8    // 匿名内部类
 9    YouCanInterface youCanInterface = new YouCanInterface() {
10      @Override
11      public String get(int i, int j) {
12        return i + "--" + j;
13      }
14    };
15    System.out.println(youCanInterface.get(1, 4));
16
17    // lambda表达式
18    YouCanInterface youCanInterface1 = (i, j) -> {
19      return i + "---" + j;
20    };
21    System.out.println(youCanInterface1.get(1, 5));
22  }
23}

Lambda表达式部分应用

集合遍历

 1public class Test03 {
 2  public static void main(String[] args) {
 3    List<String> list = new ArrayList<>();
 4    list.add("B");
 5    list.add("C");
 6    list.add("A");
 7
 8    // 匿名内部类
 9    list.forEach(new Consumer<String>() {
10      @Override
11      public void accept(String s) {
12        System.out.println(s);
13      }
14    });
15
16    // lambda表达式遍历
17    list.forEach(s -> {
18      System.out.println(s);
19    });
20      
21    // 更精简
22    list.forEach(System.out::println);
23  }
24}

集合排序

 1public class Test04 {
 2  public static void main(String[] args) {
 3    List<UserEntity> userList = new ArrayList<>();
 4    userList.add(new UserEntity("xiaoming", 10));
 5    userList.add(new UserEntity("xiaogang", 8));
 6    userList.add(new UserEntity("xiaohua", 15));
 7    userList.add(new UserEntity("xiaoli", 5));
 8
 9    // 匿名内部类方法
10    userList.sort(new Comparator<UserEntity>() {
11      @Override
12      public int compare(UserEntity o1, UserEntity o2) {
13        return o1.getAge() - o2.getAge();
14      }
15    });
16    userList.forEach(new Consumer<UserEntity>() {
17      @Override
18      public void accept(UserEntity userEntity) {
19        System.out.println(userEntity);
20      }
21    });
22
23    // lambda表达式方法
24    userList.sort((o1, o2) -> o1.getAge() - o2.getAge());
25    userList.forEach(userEntity -> {
26      System.out.println(userEntity);
27    });
28
29    // 更精简
30    userList.sort(Comparator.comparingInt(UserEntity::getAge));
31    userList.forEach(System.out::println);
32  }
33}

线程调用

因为Runnable接口是函数接口

 1public class Test05 {
 2  public static void main(String[] args) {
 3    // 匿名内部类
 4    new Thread(new Runnable() {
 5      @Override
 6      public void run() {
 7        System.out.println("线程名称: " + Thread.currentThread().getName() + ", 子线程");
 8      }
 9    }).start();
10
11    // lambda表达式
12    new Thread(() -> System.out.println("线程名称: " + Thread.currentThread().getName() + ", 子线程")).start();
13  }
14}

Stream流

image-20220412075910862

  • 串行流
  • 并行流
 1public class Test01 {
 2
 3  public static void main(String[] args) {
 4    List<UserEntity> userList = new ArrayList<>();
 5    // 创建方式有两种
 6    // 第一种: 串行流
 7    Stream<UserEntity> stream = userList.stream();
 8
 9    // 第二种:并行流
10    Stream<UserEntity> userEntityStream = userList.parallelStream();
11  }
12
13}

Stream流部分应用

List集合转map

 1public class Test01 {
 2
 3  public static void main(String[] args) {
 4    List<UserEntity> userList = new ArrayList<>();
 5    userList.add(new UserEntity("xiaoming", 10));
 6    userList.add(new UserEntity("xiaogang", 8));
 7    userList.add(new UserEntity("xiaohua", 15));
 8    userList.add(new UserEntity("xiaoli", 5));
 9    userList.add(new UserEntity("xiaowang", 3));
10
11    // 创建方式有两种
12    // 第一种: 串行流
13    Stream<UserEntity> stream = userList.stream();
14
15    // 第二种:并行流
16    Stream<UserEntity> userEntityStream = userList.parallelStream();
17
18    Map<String, UserEntity> map =  stream.collect(Collectors.toMap(new Function<UserEntity, String>() {
19      // 第一个泛型UserEntity是List中泛型的类型
20      // 第二个泛型String是将要转换的Map中key的类型
21      @Override
22      public String apply(UserEntity userEntity) {
23        // 该方法是key
24        return userEntity.getUsername();
25      }
26    }, new Function<UserEntity, UserEntity>() {
27      // 第一个泛型UserEntity是List中泛型的类型
28      // 第二个泛型UserEntity是将要转换的Map中value的类型
29      @Override
30      public UserEntity apply(UserEntity userEntity) {
31        // 该方法还value
32        return userEntity;
33      }
34    }));
35
36    map.forEach(new BiConsumer<String, UserEntity>() {
37      @Override
38      public void accept(String s, UserEntity userEntity) {
39        System.out.println(s + "----" + userEntity.getUsername());
40      }
41    });
42
43    // lambda表达式简化
44    Map<String, UserEntity> map2 =  stream.collect(Collectors.toMap(UserEntity::getUsername, userEntity -> userEntity));
45    map.forEach((s, userEntity) -> System.out.println(s + "----" + userEntity.getUsername()));
46
47  }
48}

计算求和

 1public class Test02 {
 2  public static void main(String[] args) {
 3    Stream<Integer> stream = Stream.of(10, 20, 40, 60, 30);
 4    Optional<Integer> reduce = stream.reduce(new BinaryOperator<Integer>() {
 5      @Override
 6      public Integer apply(Integer num1, Integer num2) {
 7        return num1 + num2;
 8      }
 9    });
10    System.out.println(reduce.get());
11
12    // lambda精简
13    reduce = stream.reduce(Integer::sum);
14    System.out.println(reduce.get());
15
16
17    // 对象
18    List<UserEntity> userList = new ArrayList<>();
19    userList.add(new UserEntity("xiaoming", 10));
20    userList.add(new UserEntity("xiaogang", 8));
21    userList.add(new UserEntity("xiaohua", 15));
22    userList.add(new UserEntity("xiaoli", 5));
23    userList.add(new UserEntity("xiaowang", 3));
24    Optional<UserEntity> reduceEntity = userList.stream().reduce(new BinaryOperator<UserEntity>() {
25      @Override
26      public UserEntity apply(UserEntity userEntity, UserEntity userEntity2) {
27        UserEntity reduceEntity = new UserEntity("reduce", 0);
28        reduceEntity.setAge(userEntity.getAge() + userEntity2.getAge());
29        return reduceEntity;
30      }
31    });
32    System.out.println(reduceEntity.get());
33
34    // lambda精简
35    reduceEntity = userList.stream().reduce((userEntity, userEntity2) -> {
36      UserEntity reduceEntity1 = new UserEntity("reduce", 0);
37      reduceEntity1.setAge(userEntity.getAge() + userEntity2.getAge());
38      return reduceEntity1;
39    });
40    System.out.println(reduceEntity.get());
41
42  }
43}

查找集合最值元素

 1public class Test03 {
 2  public static void main(String[] args) {
 3    List<UserEntity> userList = new ArrayList<>();
 4    userList.add(new UserEntity("xiaoming", 10));
 5    userList.add(new UserEntity("xiaogang", 8));
 6    userList.add(new UserEntity("xiaohua", 15));
 7    userList.add(new UserEntity("xiaoli", 5));
 8    userList.add(new UserEntity("xiaowang", 3));
 9
10    // 最大值
11    Optional<UserEntity> max = userList.stream().max(new Comparator<UserEntity>() {
12      @Override
13      public int compare(UserEntity o1, UserEntity o2) {
14        return o1.getAge() - o2.getAge();
15      }
16    });
17    System.out.println(max.get());
18    // lambda表达式方式
19    max = userList.stream().min(Comparator.comparingInt(UserEntity::getAge));
20    System.out.println(max.get());
21
22    // 最小值
23    Optional<UserEntity> min = userList.stream().min(new Comparator<UserEntity>() {
24      @Override
25      public int compare(UserEntity o1, UserEntity o2) {
26        return o1.getAge() - o2.getAge();
27      }
28    });
29    System.out.println(min.get());
30
31    // lambda表达式方式
32    min = userList.stream().min(Comparator.comparingInt(UserEntity::getAge));
33    System.out.println(min.get());
34  }
35}

判断集合是否存在某元素

  • allMatch:所有元素都满足返回true
  • anyMatch: 只要有满足一条满足,就返回true
 1public class Test04 {
 2  public static void main(String[] args) {
 3    List<UserEntity> userList = new ArrayList<>();
 4    userList.add(new UserEntity("xiaoming", 10));
 5    userList.add(new UserEntity("xiaogang", 8));
 6    userList.add(new UserEntity("xiaohua", 15));
 7    userList.add(new UserEntity("xiaoli", 5));
 8    userList.add(new UserEntity("xiaowang", 3));
 9
10    // 集合中是否存在
11    boolean xiaoming = userList.stream().anyMatch(new Predicate<UserEntity>() {
12      @Override
13      public boolean test(UserEntity userEntity) {
14        return userEntity.getUsername().equals("xiaoming");
15      }
16    });
17    System.out.println(xiaoming);
18
19    // lambda表达式形式
20    xiaoming = userList.stream().anyMatch(userEntity -> userEntity.getUsername().equals("xiaoming"));
21    System.out.println(xiaoming);
22
23    // 集合中的源素是否满足
24    xiaoming = userList.stream().allMatch(new Predicate<UserEntity>() {
25      @Override
26      public boolean test(UserEntity userEntity) {
27        return userEntity.getUsername().equals("xiaoming");
28      }
29    });
30    System.out.println(xiaoming);
31
32    // lambda表达式形式
33    xiaoming = userList.stream().allMatch(userEntity -> userEntity.getUsername().equals("xiaoming"));
34    System.out.println(xiaoming);
35
36  }
37}

过滤器

 1public class Test05 {
 2  public static void main(String[] args) {
 3    List<UserEntity> userList = new ArrayList<>();
 4    userList.add(new UserEntity("xiaoming", 10));
 5    userList.add(new UserEntity("xiaogang", 8));
 6    userList.add(new UserEntity("xiaohua", 15));
 7    userList.add(new UserEntity("xiaoli", 5));
 8    userList.add(new UserEntity("xiaowang", 3));
 9    userList.add(new UserEntity("xiaogang", 27));
10
11    userList.stream().filter(new Predicate<UserEntity>() {
12      @Override
13      public boolean test(UserEntity userEntity) {
14        // 这里可以添加多个条件
15        // 如还需要年龄要求 可以直接加 && userEntity.getAge > 10
16        return userEntity.getUsername().equals("xiaogang");
17      }
18    }).forEach(new Consumer<UserEntity>() {
19      @Override
20      public void accept(UserEntity userEntity) {
21        System.out.println(userEntity.toString());
22      }
23    });
24
25    // lambda表达式
26    userList.stream().filter(userEntity -> {
27      // 这里可以添加多个条件
28      // 如还需要年龄要求 可以直接加 && userEntity.getAge > 10
29      return userEntity.getUsername().equals("xiaogang");
30    }).forEach(userEntity -> System.out.println(userEntity.toString()));
31  }
32}

limit和skip

  • skip:跳过n条
  • limit:从第0条开始返回n条

可以联合使用skiplimit完成分页效果。

由于limit无法选择从第几条开始,只能限制返回几条,所以可以先使用skip跳过指定条数,再使用limit来限制需要返回的条数。

 1public class Test06 {
 2  public static void main(String[] args) {
 3    List<UserEntity> userList = new ArrayList<>();
 4    userList.add(new UserEntity("xiaoming", 10));
 5    userList.add(new UserEntity("xiaogang", 8));
 6    userList.add(new UserEntity("xiaohua", 15));
 7    userList.add(new UserEntity("xiaoli", 5));
 8    userList.add(new UserEntity("xiaowang", 3));
 9    userList.add(new UserEntity("xiaogang", 27));
10
11    // 输出xiaoli和xiaowang两条记录
12    userList.stream().skip(3).limit(2).forEach(userEntity -> {
13      System.out.println(userEntity.toString());
14    });
15
16  }
17}

排序

 1public class Test07 {
 2  public static void main(String[] args) {
 3    List<UserEntity> userList = new ArrayList<>();
 4    userList.add(new UserEntity("xiaoming", 10));
 5    userList.add(new UserEntity("xiaogang", 8));
 6    userList.add(new UserEntity("xiaohua", 15));
 7    userList.add(new UserEntity("xiaoli", 5));
 8    userList.add(new UserEntity("xiaowang", 3));
 9    userList.add(new UserEntity("xiaogang", 27));
10
11    userList.stream().sorted(Comparator.comparingInt(UserEntity::getAge)).forEach(System.out::println);
12
13  }
14}

并行流

利用500亿以内的数累加求和来测试

  • 串行流

     1public class Test08 {
     2  public static void main(String[] args) {
     3    Instant start = Instant.now();
     4    long sum = 0;
     5
     6    for (long i = 0; i < 50000000000L; i++) {
     7      sum += i;
     8    }
     9
    10    System.out.println(sum);
    11    Instant end = Instant.now();
    12
    13    System.out.println("【串行流】500亿累加求和用时:" + (Duration.between(start, end).toMillis()));
    14
    15    // 打印结果:
    16    // -4378597037249509888
    17    // 【串行流】500亿累加求和用时:11279
    18  }
    19}
    
  • 串行流

     1public class Test09 {
     2  public static void main(String[] args) {
     3    Instant start = Instant.now();
     4
     5    LongStream longStream = LongStream.rangeClosed(0, 50000000000L);
     6    OptionalLong result = longStream.parallel().reduce(new LongBinaryOperator() {
     7      @Override
     8      public long applyAsLong(long left, long right) {
     9        return left + right;
    10      }
    11    });
    12
    13    System.out.println(result.getAsLong());
    14    Instant end = Instant.now();
    15
    16    System.out.println("【并行流】500亿累加求和用时:" + (Duration.between(start, end).toMillis()));
    17
    18    // 打印结果
    19    // -4378596987249509888
    20    //【并行流】500亿累加求和用时:5416
    21  }
    22}
    

    采用多线程分段计算来增加计算速度。

    fork join

对象判空

常用的API:

  • Optional.ofNullable()
  • Optional.of()
  • isPresent()
 1public class Test01 {
 2  public static void main(String[] args) {
 3    String username = null;
 4    // 允许传递的对象为空
 5    Optional<String> optional = Optional.ofNullable(username);
 6    // 代码将在这一行抛出异常
 7    String getUsername = optional.get();
 8    System.out.println(getUsername);
 9
10    String username1 = null;
11    // 不允许传递的对象为空
12    // 代码将在这一行抛出异常
13    Optional<String> optional2 = Optional.of(username1);
14    String getUsername1 = optional.get();
15    System.out.println(getUsername1);
16
17
18    // ofNullable和isPresent联合使用
19    // 优先判断是否为空
20    String username3 = null;
21    // 允许传递的对象为空
22    Optional<String> optional3 = Optional.ofNullable(username3);
23    // 如果username3为空,则返回false,否则返回true
24    boolean isPresent = optional.isPresent();
25    System.out.println(isPresent);
26  }
27}

默认值

  • orElse()
 1public class Test02 {
 2  public static void main(String[] args) {
 3    String username = null;
 4    // 允许传递的对象为空
 5    Optional<String> optional = Optional.ofNullable(username);
 6    // 如果对象为空则使用默认值
 7    String orElseUsername = optional.orElse("默认值");
 8    System.out.println(orElseUsername);
 9  }
10}

条件过滤

  • filter()

    返回值依然是Optional对象

 1public class Test03 {
 2  public static void main(String[] args) {
 3    String username = "测试过滤";
 4    // 允许传递的对象为空
 5    Optional<String> optional = Optional.ofNullable(username);
 6    // 如果对象为空则使用默认值
 7    Optional<String> filter = optional.filter(new Predicate<String>() {
 8      @Override
 9      public boolean test(String s) {
10        return s.equals("测试过滤");
11      }
12    });
13
14    // 返回的依然是一个Optional
15    // 如果过滤结束此处没有值了,这里会报错
16    System.out.println(filter.get());
17
18    // lambda简化
19    Optional<String> filter1 = optional.filter(s -> s.equals("测试过滤"));
20    System.out.println(filter1.get());
21  }
22}

案例

将给定对象一个属性字符串中的英文字符全部改成大写

 1public class Test04 {
 2  public static void main(String[] args) {
 3    MessageEntity messageEntity = new MessageEntity("test01", "TEst01");
 4    String result = Optional.ofNullable(messageEntity)
 5      // messageEntity1 为前面传入的messageEntity
 6      .map(messageEntity1 -> messageEntity.getMsg())
 7      // message 为传入的messageEntity.getMsg()
 8      .map(mesesage -> mesesage.toUpperCase(Locale.ROOT))
 9      .orElse(null);
10    System.out.println(result);
11  }
12}
— END —