JDK8 学习笔记

2023-11-08

JDK7

try-catch 支持处理多异常

try{
 ...;   
}catch( Exc   |   Exc  ){
    //一个catch 捕获多个异常,字节码文件跟小
}

数字类型 支持下划线

int num = 123_345;
float num2 = 222+33F;
long num3 = 123_000_111L;

switch 支持 string

switch(){
    case "java":
        break;
        ....;
    default:
          break;
}

JDK8

Lambda 表达式 函数式接口

表示行为 传递的一种方式,代替匿名内部类

(参数)-> 函数主体

函数式接口

只有一个抽象方法

@FunctionalInterface

用在接口上

表示此接口会生成一个函数式接口

@FunctionalInterface 
public interface aa{ String go(); }

不符合要求 编译器会报错

java自带的 函数式接口

@FunctionalInterface 
public interface Predicate<T>{ boolean test(T t); }
​
public static <T> List<T> filter(List<T> list , Predicate<T> p){
    List<T> resuts = new ArrayLsit<>();
    for(T s: list){
        if(p.test(s)){
            results.add(s);
        }
    }
    return results;
}
​
Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();

——————————————————————————

@FunctionalInterface 
public interface Consumer<T>{ void accept(T t); }
​
public static <T> void forEach(list,Consumer<T> c) {
    for(T i: list){
        c.accept(i);
    }
}
​
//Lambda 是 Consumer 中 accept方法的实现
forEach(Arrays.asList(1,2,3,4,5),(Integer i) -> System,out.println(i) );

————————————————

类型转换 入参T 出参R

@FunctionalInterface 
public interface Function<T,R>{
    R apply(T t);
}
​
public static <T,R> List<R> map(List<T> list, Function<T,R> f){
    List<R> result = new ArrayList<>();
    for(T s:list){
        result.add(f.apply(s));
    }
    return result;
}
​
//[7,2,6]
//lambda是 Function 接口的 apply方法实现
List<Intefer> 1 =map(Arrays.asList("lambdas","in","action"),(String s)-> s.length());

——————————————————

使用

    //断言
    void predicate(){
        Predicate<String> namesStartingWithS = name -> name.startsWith("s");
        boolean hello = namesStartingWithS.test("Hello");  //false
    }
​
    //消费数据
    void consumer(){
        Consumer<String> messageConsumer = message -> System.out.println(message);
        messageConsumer.accept("Learn java8"); //Learn java8
    }
​
    //转换
    void function(){
        Function<String ,String> toUpperCase = name -> name.toUpperCase();
        toUpperCase.apply("java"); //java
    }
​
    //提供数据
    void supplier(){
        Supplier<String> uuidGenerator =() -> UUID.randomUUID().toString();
        System.out.println(uuidGenerator.get());//输出一个 UUID
    }

::

构造器引用

    //构造器引用
    Supplier<FunctionalDemo> obj = FunctionalDemo :: new;
    FunctionalDemo f = obj.get(); 

数组引用

//数组引用
Function<Integer , String[]> fun = x->new String[x];
String[] strs = fun.apply(10);
System.out.println(strs.length);
​
Function<Integer , String[]> fun1 =String[]::new;
strs = fun1.apply(10);
System.out.println(strs.length);

异常,函数式接口都不运行抛出 受检异常

Exception 就是受检异常

RuntimeException

如果出现这类异常,包装处理

Function<BufferedReader ,String> f = (BufferedReader b)->{
    try {
      return b.readLine();
    }catch (IOException e){
        e.printStackTrace();//输出包装栈信息
        throw new RuntimeException(e);
    }
};

默认方法- 接口 default

  • 类中的方法 优先级最高,类或父类中声明的方法的优先级高于任何声明为默认方法的优先级。

定义一个接口

interface A{
    int add();
    int deleete();
    
    //defaul 修饰的一个默认方法, 不需要实现类全部实现
    default int mod(int a,int b){
        return a%b;
    }
}
​
//调用, 不需要有实现类 实现default 的实现,可以直接调用
void main(){
    ... a = new A();
    int c = a.mod(a,b);
}     //声明一个 空 opttiona
        Optional<Object> empty = Optional.empty();
​
        //依赖一个非空的 Optional
        Optional<FunctionalDemo> functionalDemo = Optional.of(new FunctionalDemo());
​
        //可以接收null 的 Optional
        Optional<FunctionalDemo> functionalDemo1 = Optional.ofNullable(new FunctionalDemo());
    

接口静态方法

interface A{
    static A getA(){
        return new A实现类();
    }
}
​
​

Optional 干掉空指针

public class UserBO{
    private AddUser user;  //对象可能空指针
    private Optional<AddUser> optUser; //对象可以为空, 但不是null
}
​
void main(){
         //声明一个 空 opttiona
        Optional<Object> empty = Optional.empty();
​
        //依赖一个非空的 Optional  不会出现非空异常
        Optional<FunctionalDemo> functionalDemo = Optional.of(new FunctionalDemo());
​
        //可以接收null 的 Optional
        Optional<FunctionalDemo> functionalDemo1 = Optional.ofNullable(new FunctionalDemo());  
}
  • Optional 类支持多种方法, map,flatMap,filter.limite

List<Project> projects = Project.buildDate();
List<String> names =projects.stream()
    .filrer(p->p.getStars()>1000)  //筛选 star大于1000的项目
    .map(Project::getName)         //提取项目名称
    .limit(3)
    .collect(Collectors.toList());  //将名称保存在List中
System.out.println(names);

Steram

  • 集合与流

    • List<String> names =
          projects.stream()  //建立操作流水线
          .filter(p-> p.getStars() >1000) //筛选出 star 比较高的香
          .map(Project::getName) //获取项目名称
          .limit(3) //只选前3个
          .conllect(Conllectors.toList()); //结果保存在另一个 List中
  • 内部迭代,外部迭代

  • 中间操作,终端操作

  • 流是"从支持数据处理操作的源生成一系列的元素"

  • 流利用内部迭代:丢带通过filter、map、sorted等操作

  • 流操作有两类:中间操作和终端操作

  • filter和map等中间操作会返回一个流,可以用它们来设置一条流水线

  • forEach和count等终端操作返回一个非流的值

  • 流中的元素按需计算的

Stream API

  • 创建流 Stream.of Arrays.Stream

    • //集合 创建流对象
      List<String> list = Arrays.asList("hello", "world");
      Stream<String> stream = list.stream();
    • //数组创建流对象
      String[] names = {"chaim","peter","john"};
      Stream<String> stream1 = Arrays.stream(names); 
    • //值 
      Stream<String> aa = Stream.of("aa", "bbb", "cc");
    • //文件流
      try (Files.lines(Paths.get("文件路径"), Charset.defaultCharset())){
          //操作
      }catch (IOException e){
          
      }
    • // iterator 创建无限流
      Stream.iterate(0,n-> n+2)
              .limit(10)
              .forEach(System.out::println);
  • 筛选 filter limit distinct skip

    • // filter 筛选 接收一个lambda表达式作为参数,该表达式返回boolean 在执行过程中,流将该元素注意输送给filter,并筛选出执行结果为true的元素
              List<Object> result = list.stream()
                      .filter()//( aa::isNull)筛选条件
                      .collect(Collectors.toList());
    • //distinct 去重
      Stream<Integer> number = Stream.of(1, 2, 2, 3);
      number.distinct().forEach(n->System.out.println(n));//1,2,3
    • //limit 截取
      Stream<Integer> number1 = Stream.of(1, 2, 2, 3);
      number1.distinct().limit(2).forEach(n->System.out.println(n));//1,2
    • //skip 跳过
      Stream<Integer> number2 = Stream.of(1, 2, 2, 3);
      number2.distinct().skip(2).forEach(n->System.out.println(n));//2,3
  • 映射 map flatMap

  • 匹配 anyMatch allMatch noneMatch findAny findFirst

    • anyMacth 判断流中是否存在至少一个元素满足指定条件,这个条件通过Lambda表达式传递给anyMatch,执行结果为 boolean类型,如,判断是都所有人都是学生

      boolean result = list.stream()
          .anyMatch(Person::isStudent);
    • allMatch 判断流中的所有元素是否都满足指定条件,这个判断条件通过Lambda表达式传递给anyMatch,执行结果为boolean类型,如,判断所有是否都是学生

      boolean result = list.stream()
          .allMatch(Person::isStudent);
    • noneMatch 是否未匹配所有元素 流中的所有元素都不满足条件

      boolean result = list.stream()
          .noneMatch(Person::isStudent);
    • findAny 获取任一元素 从流中随机选出一个元素来,返回一个Optional类型元素

      Optional<Person> person =list.stream().findAny();
    • findFirst 获取第一个元素

      Optional<Person> person =list.stream().findFirst();
  • 归约 reduce

    • 归约是将集合中的所有元素经过指定运算,折叠成一个元素输出,如 最值,平均值,这些操作都是将集合的的元素折叠成一个元素输出

    • reduce 实现归约 这个函数接收两个参数 1.初始值 2.进行归约操作的Lambda表达式

      //计算所有人的年龄总和
      int age = list.stream().reduce(0,(person1,person2)->person1.getAge()+pesrson2.getAge());

  • 数值流 lntStream LongStream DoublieStream

    • 采用reduce 进行数值操作会涉及到基本数据类型和引用数据类型之间的装箱,拆箱操作,因此效率比较低,当流操作为纯数值操作时,使用数值流能获得较高的效率

    • StreamAPI提供了 三种方法 mapToint 、mapToDoubile 、mapToLong

      IntStream stream = list.stream().mapToInt(Person::getAge);

Collectors

maxBy 求最值

Optional<aa> collect = aa.stream()
    .collect(maxBy(Comparator.comparingInt(aa::getStars)));

sumingInt 求和

Optional<aa> collect = aa.stream()
    .collect(sumingInt(aa::getStats));

averaginInt 求平均

Optional<aa> collect = aa.stream()
    .collect(averagingInt(Comparator.comparingInt(aa::getStars)));

joining 连接字符

String.of("hello","java8")
    .collect(joining("="));
//结果 hello=java8

tream 操作

流创建在数据源上的,java.util.Collection 、list 集合和set集合都是数据源的一种产生的流可以是串行的,也可是并行的。通过集合类的Stream方法可以产生串行流,parallelStream 方法可以产生并行流

Stream支持的主要连续操作如下

  • filter: 接受一个 predicate 来过滤流中的所有元素

  • sorted: 返回流中已排序版本

  • map: 通过指定的函数将流中的每一个元素转变为另外的对象

  • flatMap: 每个元素沌河得到的是Stream 对象,会把子Stream 中的元素压缩到父集合

  • peek: 生成一个包含原Stream 的所有元素的新 Stream

  • limit: 生成一个包含原Stream 进行截断操作

  • skip: 返回一个丢弃原Stream 的前N 个元素后剩下元素组成的新 Stream

  • reduce: 使用指定的函数对流中元素实施消减,返回一个包括所有被元素消减元素的Optional

  • collect: 把流中的元素聚合到其他数据结构中

  • match :anyMatch、allMatch 等各种匹配操作可以用来检测是否某种 predicate 和流中元素相匹配

  • count : 返回流中的元素数量

  • findFirst: 返回Stream中的第一个元素

  • max和min: 使用给定的比较器(Operator),返回Stream 中的最大值\最小值

注意:使用Stram需要关注

  1. 流并不存储值,它只是某数据源的一个视图,对流的操作会产生一个结果,但流的数据源不会被修改

  2. 使用stream 时,要遵循先做filte 在map 原则

  3. 多数Stream 操作(包括 filter 、 映射map 、排序 sorted 以及去重 distinct ) 都以惰性方式实现

  4. 不同于其他 Stream 操作,flatMap 不是惰性计算

  5. Stream 只能被 "消费" 一次,一旦遍历过就会失效

  6. 慎重使用并行Stream ,其底层使用的是 ForkJoinPool 的commonPool 。在不做任何配置的情况下,所有并行流都共用同一个线程池(默认线程数为机器CPU 数目,可通过系统属性 java.util.concurrent.ForkJoinPool.common.parallelism 设置 ),而且此线程池还会被其他机制依赖

并行流

直接list调用 parallel方法

list.stream()
    .parallel()

时间日期API

Date和Calendar 不是线程安全的,需要编写额外的代码来处理线程安全问题

  • Zoneld : 时区ID 用来确定Instant 和 LoaclDateTime 互相转换的规则

    • //获取系统默认时区
      ZoneId zoneId = ZoneId.systemDefault();
      ZoneId shanghai = ZoneId.of("Asia/Shanghai");
      ​
      //TimeZone 转换为 ZoneId
      ZoneId zoneId1 = TimeZone.getDefault().toZoneId();
  • Instant: 用来表示时间线上的一个点

  • LocalDate 表示没有时区的日期,LocalDate 是不可变并且线程安全的

  • LocalTime 表示没有时区时间,LocalTime是不可变且线程安全的

  • LocalDateTime 表示没有时区的日期时间,LocalDateTime 是不可变并且先安全的

  • Clock 用于访问当前时刻,日期,用到的时区

CompletableFuture

  • 创建 CompletableFunture

  • 处理计算结果

  • 转换结果

  • 异常处理

  • 消耗型

  • 组合 Either

  • allOf anyOf

Map 增强改动

Map <String,String> map = new HashMap<>();
map.putIfAbsent("1","a");
map.forEach((k,v) - > {
    System.out.println(k+v);
});
map.computeIfAbsent("2",e -> e+ "1");
map.computeIfPresent("1",(k,v) -> k+v );
​
map.remove("1" ,"a");
​
map.getOrDefault("2","b");
map.merge("1","a",(k,v) -> k+v );
  • putlfAbsent: 当key 没哟对应的value 时才放入新的值,可以防止旧值被覆盖

  • forEach: 方便对 map做遍历

  • computelfAbsent: 当key 没有对应的value 时才计算生成的新值

  • computelfPresent: 当key 有对应的value ,使用key 和value 生成新的 value

  • remove(k,v): 仅当k 对应的value 等于v 时,才会删除k

  • getOrDefault: 获取不到值时使用传入的默认值

  • merge: 如果key 对应的值存在,那么将对应的value 和传入的value使用后的函数并合作为新值,否则设置传入的value

底部

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JDK8 学习笔记 的相关文章

随机推荐

  • 深度学习图像增强---python库imgaug

    图像增强python库imgaug landmark 增强 segmentation 增强 imgaug用来做图像增强的一个python库 1 图像增强是在小样本以及提高模型泛化能力的通常采用的措施 下面总结一下我之前用到过的一些内容 la
  • 虚拟机网卡不见了

    有的时候不知道为什么虚拟机就是不能上网 郁闷 排除了虚拟机网卡被禁用之类的原因的话 看下系统时间 如果没有跟物理机器时间一致 改成一样试试看
  • DBA典型的工作职责

    下面不是全部列表 但是包括了DBA的典型职责 把监视数据库实例当作每日必做工作以保证其可用性 解决不可用的问题 收集系统统计和性能信息以便定向和配置分析 配置和调整数据库实例以便在应用程序特定要求下达到最佳性能 分析和管理数据库安全性 控制
  • diff和patch使用指南

    diff和patch是一对工具 在数学上来说 diff是对两个集合的差运算 patch是对两个集合的和运算 diff比较两个文件或文件集合的差异 并记录下来 生成一个diff文件 这也是我们常说的patch文件 即补丁文件 patch能将d
  • 苹果手机忘记密码锁屏了怎么办,有什么处理方法可解

    我们平时用手机 不管什么牌子的手机 都会设置锁屏密码 是为更好的保护自己的隐私信息 但人有时候就是会犯这样的蠢事 蠢到自己都想哭 就是忘记锁屏密码 手机打不开 要是遇到什么急事 真的是快被自己气死 以苹果手机为例 那接下来由小编分享苹果手机
  • Prometheus(五)——PromQL介绍

    这里写自定义目录标题 PromQL介绍 基本用法 查询时间序列 完全匹配 正则匹配 范围查询 时间位移操作 使用聚合操作 标量和字符串 标量 Scaler 字符串 合法的PromQL表达式 合法规则 标签名称的表达 PromQL操作符 数学
  • tq210-uboot spl 和 stage 2 启动

    将OK210的代码稍微改了改 如下 1 mem初始化更改 因为ok210为512M 而tq210为1G内存 2 ok210使用串口0为debug 口 3 ok210的sd卡在通道0上 主要是利用SD卡启动 SOC首先读取SD的SPL部分到s
  • Mybatis中关于返回值的问题

    Mybatis中关于返回值的问题 结论 在Mybatis的xml中 可以使用resultType 来指定其返回值的类型 但如果sql语句执行的结果为空 则会返回null 问题描述 在写Mybatis中的select语句 因为查找的条件 很有
  • 11.全志H3-AD使用记录

    上面是我的微信和QQ群 欢迎新朋友的加入 修改PCB默认字体 网上大多数教程都是改这里 我的操作是这个default里面 从头找到尾 凡是丝印层的 全改成自己想要的字体 原理图选中之后 PCB没有变化
  • 华清 c++ day5 9月12

    ifndef HOMEWORK H define HOMEWORK H include
  • 分治法( Divide and Conquer)

    分治法也称为分解法 分治策略等 分治法算法思想如下 1 将一个问题划分为同一类型的若干子问题 子问题最好规模相同 2 对这些子问题求解 一般使用递归方法 但在问题规模足够小时 有时也会利用另一个算法 3 有必要的话 合并这些子问题的解 以得
  • 《算法零基础100讲》 最值算法

    题目1 题目链接 int findMaxConsecutiveOnes int nums int numsSize int cnt 0 int max 0 for int i 0 i
  • Java项目校园兼职平台(含代码)

    一 项目分析 1 本平台根据角色定位不同有不同的模块 首先系统有一个登录注册模块 属于兼职人员的模块有个人信息管理和兼职申请 属于管理员的模块有基本信息维护 兼职信息投放和系统管理 2 平台登录注册 用户可以通过账号密码登录平台 如果用户是
  • error: You have not concluded your merge (MERGE_HEAD exists).git拉取失败

    拉取git上的更新时出现错误如下 error You have not concluded your merge MERGE HEAD exists hint Please commit your changes before mergin
  • 何为PostgreSQL?

    PostgreSQL是以加州大学伯克利分校计算机系开发的POSTGRES 版本 4 2为基础的对象关系型数据库管理系统 ORDBMS POSTGRES 领先的许多概念在很久以后才出现在一些商业数据库系统中 PostgreSQL是最初的伯克利
  • OculusRiftS与Unity.UI的交互(6)-播放视频

    1 在Hierarchy空白处点右键 gt CreateEmpty 创建出一个空节点 并命名为Video 2 在这个Video的Inspector中 点击AddComponent 添加组件 VideoPlayer 添加完成后 将视频素材拖入
  • npm构建脚本_NPM脚本简介

    npm构建脚本 by Mohammed Ajmal Siddiqui 由Mohammed Ajmal Siddiqui NPM脚本简介 Introduction to NPM Scripts NPM scripts are among my
  • 享元模式详解

    享元模式 即共享元素 主要用于减少创建对象的数量以减少系统的复杂度 应用实例有池技术如数据库连接池 线程池等 享元模式尝试重用现有的同类对象 如果未找到匹配的对象 则创建新对象 比如说你有通过单车出行的需求 正好有共享单车来满足你的需求 这
  • Linux磁盘空间占满,但搜不到大文件

    使用 df h 查看磁盘空间 使用 du sh 查看每个目录的大小 经过查看没有发现任何大的文件夹 继续下面的步骤 如果您的Linux磁盘已满 但是通过 du sh 找不到大文件 可能是因为有一些进程正在写入磁盘 但是这些文件已经被删除 但
  • JDK8 学习笔记

    JDK7 try catch 支持处理多异常 try catch Exc Exc 一个catch 捕获多个异常 字节码文件跟小 数字类型 支持下划线 int num 123 345 float num2 222 33F long num3