学习目标

  • Lambda表达式
    • 函数式思想
    • 函数式接口
    • Lambda表达式的使用前提
    • Lambda表达式的操作案例
  • Stream流
    • Stream流的优势
    • Stream流-获取功能
    • Stream流-中间功能
    • Stream流-终结功能
  • 多线程入门

    • 多线程实现的方式
    • Thread类常用功能

      1. Lambda表达式

      1.1 Lambda表达式的优势 ?

      代码更少,关注点更加明确

      1.2 Lambda表达式使用前提和格式 ?

  • 前提:

    • 必须有一个函数式接口
    • 接口中有且只有一个抽象方法
  • 格式:
    • (形式参数)->{代码块}
  • 函数式接口
    • 标志性注解@FunctionalInterface

      1.3 Lambda代码实现(有参有返回值)

      1. public class LambdaTest4 {
      2. public static void main(String[] args) {
      3. //Lambda表达式,参数与接口匹配
      4. useCalculator((int a,int b) -> {return a+b;});
      5. }
      6. //useCalculator方法,实现接口
      7. public static void useCalculator(Calculator calculator){
      8. int i = calculator.calc(10, 20);
      9. System.out.println(i);
      10. }
      11. }
      12. //定义一个函数式接口
      13. @FunctionalInterface
      14. interface Calculator{
      15. //抽象方法
      16. public abstract int calc(int a,int b);
      17. }

      1.4 Lambda表达式和匿名内部类的区别

      | | Lambda表达式 | 匿名内部类 | | —- | —- | —- | | 所需类型 | 只能是函数式接口 | 接口,抽象类,具体类 | | 使用限制 | 只作用在有且仅有一个抽象方法需要重写 | 一个或多个抽象方法需要重写 | | 实现原理 | 编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成 | 编译之后,产生一个单独的.class字节码文件 |

2. Stream流

2.1 Stream流存在的优势 , 什么时候使用Stream流 ?

对集合,数组当中的元素做筛选和过滤使用。更加方便,更加简洁。

2.2 Stream流获取方法

  1. //获取单列集合
  2. ArrayList<String> list = new ArrayList<>();
  3. list.stream().forEach(s -> System.out.println(s));
  4. //获取双列集合(双列集合的键和值需要分开获取)
  5. HashMap<String, String> map = new HashMap<>();
  6. map.keySet().stream().forEach(s -> System.out.println(s));
  7. map.entrySet().stream().forEach(s -> System.out.println(s));
  8. //获取数组
  9. int[] arr={1, 2, 3, 4, 5, 6};
  10. Arrays.stream(arr).forEach(s -> System.out.println(s));

2.3 Stream流中间方法

  1. //filter用于对流中的数据进行过滤
  2. list.stream().filter(s -> s.length()==2).forEach(s -> System.out.println(s));
  3. //limit截取指定参数个数的数据
  4. list.stream().limit(3).forEach(s -> System.out.println(s));
  5. //skip跳过指定参数个数的数据
  6. //distinct()去除流中重复的元素。依赖(hashCode和equals方法)
  7. //concat(Stream a, Stream b)合并a和b两个流为一个流
  8. //Stream.concat(list1.stream(),list2.stream()).forEach(s -> System.out.println(s));
  9. //sorted()将流中元素按照自然排序的规则排序
  10. //Stream<T> sorted (Comparator<? super T> comparator) : 将流中元素按照自定义比较器规则排序
  11. list.stream().sorted(new Comparator<String>() {
  12. @Override
  13. public int compare(String o1, String o2) {
  14. return o1.length()-o2.length();
  15. }
  16. }).forEach(s -> System.out.println(s));

2.4 Stream流终结方法

  1. //1.long count():返回此流中的元素数
  2. long count = list.stream().count();
  3. //2.void forEach(Consumer action):对此流的每个元素执行操作
  4. Consumer接口中的方法 void accept(T t):对给定的参数执行此操作
  5. list.stream().forEach( (String s) -> {
  6. System.out.println(s);
  7. });

2.5 Stream流的获取功能

  1. public class StreamDemo6 {
  2. public static void main(String[] args) {
  3. ArrayList<Integer> list = new ArrayList<>();
  4. for (int i = 0; i < 10; i++) {
  5. list.add(i);
  6. }
  7. //Stream流的收集方法
  8. //R collect(Collector collector) : 此方法只负责收集流中的数据 , 创建集合添加数据动作需要依赖于参数
  9. //public static <T> Collector toList():把元素收集到List集合中
  10. List<Integer> l = list.stream().limit(3).collect(Collectors.toList());
  11. System.out.println(l);
  12. //public static <T> Collector toSet():把元素收集到Set集合中
  13. Set<Integer> set = list.stream().filter(num -> num % 2 == 0).collect(Collectors.toSet());
  14. System.out.println(set);
  15. //public static Collector toMap(Function keyMapper,Function valueMapper):把元素收集到Map集合中
  16. ArrayList<String> list2 = new ArrayList<>();
  17. list2.add("zhangsan,23");
  18. list2.add("lisi,24");
  19. list2.add("wangwu,25");
  20. Map<String, String> map = list2.stream().filter(s -> Integer.parseInt(s.split(",")[1]) > 23).collect(Collectors.toMap((String s) -> {
  21. return s.split(",")[0];
  22. },
  23. (String s) -> {
  24. return s.split(",")[1];
  25. }));
  26. System.out.println(map);
  27. }
  28. }

3. 多线程实现的方式

3.1 多线程实现方式区别 ?

3.1.1 继承Thread类

  1. public class MyThread01 {
  2. public static void main(String[] args) {
  3. //创建线程对象,调用线程的start方法开启线程
  4. MyThread th = new MyThread();
  5. th.start();
  6. for (int i = 0; i < 1000; i++) {
  7. System.out.println(i);
  8. }
  9. }
  10. }
  11. //创建一个类继承Thread类
  12. class MyThread extends Thread{
  13. //在类中重写run方法(线程执行的任务放在这里)
  14. @Override
  15. public void run(){
  16. for (int i = 0; i < 1000; i++) {
  17. System.out.println(getName()+".."+i);
  18. }
  19. }
  20. }

3.1.2 实现Runnable接口

  1. public class MyThread02 {
  2. public static void main(String[] args) {
  3. //创建任务对象
  4. MyRunnable myRunnable = new MyRunnable();
  5. //使用含有Runnable参数的构造方法,创建线程对象并指定任务
  6. Thread thread = new Thread(myRunnable);
  7. //调用线程的start方法,开启线程
  8. thread.start();
  9. for (int i = 0; i < 1000; i++) {
  10. System.out.println(i);
  11. }
  12. }
  13. }
  14. //定义任务类实现Runnable
  15. class MyRunnable implements Runnable{
  16. //重写run方法
  17. @Override
  18. public void run() {
  19. for (int i = 0; i < 1000; i++) {
  20. System.out.println(Thread.currentThread().getName()+":"+i);
  21. }
  22. }
  23. }

3.1.3 Thread类中常用方法

  • String getName():返回此线程的名称
  • void setName(String name):将此线程的名称更改为等于参数 name
  • public static Thread currentThread() :返回对当前正在执行的线程对象的引用
  • public static void sleep(long time):让线程休眠指定的时间,单位为毫秒。
  • public void join() : 具备阻塞作用 , 等待这个线程死亡,才会执行其他线程

    4. Optional类API

  • public static Optional of(T value) : 通过非null值构建一个Optional容器,注意value不能不为null否则抛出异常

  • public static Optional ofNullable(T value) : 通过指定值构建一个Optional容器,如果值为null则返回Optional.empty
  • public T orElse(T other) : 返回值如果存在,否则返回 other 。
  • public boolean isPresent() : 如果对象为null返回的是false , 如果对象不为null返回的是true
  • public T get() : 如果 Optional中存在值,则返回值,否则抛出 NoSuchElementException