范文健康探索娱乐情感热点
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

Java8特性大全(最新版)

  一、序言
  Java8 是一个里程碑式的版本,凭借如下新特性,让人对其赞不绝口。  Lambda 表达式给代码构建带来了全新的风格和能力;  Steam API 丰富了集合操作,拓展了集合的能力;  新日期时间 API 千呼万唤始出来;
  随着对 Java8 新特性理解的深入,会被 Lambda 表达式(包含方法引用)、流式运算的美所迷恋,不由惊叹框架设计的美。  二、方法引用
  Lambda 表达式是匿名函数,可以理解为一段可以用参数传递的代码(代码像数据一样传递)。Lambda 表达式的使用需要有函数式接口的支持。 方法引用是对特殊 Lambda 表达式的一种简化写法,当 Lambda 体中只调用一个方法,此方法满足函数式接口规范,此时可以使用    ::     方法引用语法。
  从语法表现力角度来讲,     方法引用 > Lambda表达式 > 匿名内部类     , 方法引用是高阶版的 Lambda 表达式,语言表达更为简洁,强烈推荐使用。
  方法引用表达式无需显示声明被调用方法的参数,根据上下文自动注入。方法引用能够提高 Lambda 表达式语言的优雅性,代码更加简洁。下面以     Comparator     排序为例讲述如何借助方法引用构建优雅的代码。 (一)方法引用与排序1、普通数据类型
  普通数据类型相对较容易理解。  // 正向排序(方法引用) Stream.of(11, 15, 11, 12).sorted(Integer::compareTo).forEach(System.out::println); // 正向排序 Stream.of(11, 15, 11, 12).sorted(Comparator.naturalOrder()).forEach(System.out::println); // 逆向排序 Stream.of(11, 15, 11, 12).sorted(Comparator.reverseOrder()).forEach(System.out::println);2、对象数据类型(1)数据完好
  数据完好有两重含义,一是对象本身不为空;二是待比较对象的属性值不为空,以此为前提进行排序操作。  // 对集合按照年龄排序(正序排列) Collections.sort(userList, Comparator.comparingInt(XUser::getAge)); // 对集合按照年龄排序(逆序排列) Collections.sort(userList, Comparator.comparingInt(XUser::getAge).reversed());
  此示例是以     Integer     类型展开的,同理    Double     类型、    Long     类型等数值类型处理方式相同。其中   Comparator   是排序过程中重要的类。 (2)数据缺失
  数据缺失的含义是对象本身为空或者待比较对象属性为空,如果不进行处理,上述排序会出现空指针异常。 最常见的处理方式是通过流式运算中     filter     方法,过滤掉空指针数据,然后按照上述策略排序。 userList.stream().filter(e->e.getAge()!=null).collect(Collectors.toList());3、字符串处理
  少数开发者在构建实体类时,     String     类型遍地开花,在需要运算或者排序的场景下,String 的缺陷逐渐暴露出来。下面讲述    字符串数值     类型排序问题,即不修改数据类型的前提下完成期望的操作。 实体类 public class SUser {     private Integer userId;     private String UserName;     // 本应该是Double类型,错误的使用为String类型     private String score; }
  正序、逆序排序  // 对集合按照年龄排序(正序排列) Collections.sort(userList, Comparator.comparingDouble(e -> new Double(e.getScore())));
  数据类型转换排序时,使用 JDK 内置的 API 并不流畅,推荐使用     commons-collection4     包中的排序工具类。了解更多,请移步查看   ComparatorUtils   。 // 对集合按照年龄排序(逆序排列) Collections.sort(userList, ComparatorUtils.reversedComparator(Comparator.comparingDouble(e -> new Double(e.getScore()))));
  小结:通过以排序为例,实现 Comparator 接口、Lambda 表达式、方法引用三种方式相比较,代码可读性逐步提高。  (二)排序器
  内置的排序器可以完成大多数场景的排序需求,当排序需求更加精细化时,适时引入第三方框架是比较好的选择。  1、单列排序
  单列排序包含正序和逆序。  // 正序 Comparator comparator = Comparator.comparing(XUser::getUserName); // 逆序 Comparator comparator = Comparator.comparing(XUser::getUserName).reversed();2、多列排序
  多列排序是指当待比较的元素有相等的值时,如何进行下一步排序。  // 默认多列均是正序排序 Comparator comparator = Comparator.comparing(XUser::getUserName)     .thenComparing(XUser::getScore);// 自定义正逆序 Comparator comparator = Comparator.comparing(XUser::getUserName,Comparator.reverseOrder())     .thenComparing(XUser::getScore,Comparator.reverseOrder());三、Steam API
  流的操作包含如下三个部分:创建流、中间流、关闭流,     筛选     、    去重     、    映射     、    排序     属于流的中间操作,    收集     属于终止操作。   Stream   是流操作的基础关键类。 (一)创建流(1)通过集合创建流// 通过集合创建流 List lists = new ArrayList<>(); lists.stream();(2)通过数组创建流// 通过数组创建流 String[] strings = new String[5]; Stream.of(strings);
  应用较多的是通过集合创建流,然后经过中间操作,最后终止回集合。  (二)中间操作1、筛选(filter)
  筛选是指从(集合)流中筛选满足条件的子集,通过 Lambda 表达式生产型接口来实现。  // 通过断言型接口实现元素的过滤 stream.filter(x->x.getSalary()>10);非空过滤
  非空过滤包含两层内容:一是当前对象是否为空或者非空;二是当前对象的某属性是否为空或者非空。 筛选非空对象,语法     stream.filter(Objects::nonNull)     做非空断言。 // 非空断言 java.util.function.Predicate nonNull = Objects::nonNull;
  查看   Objects   类了解更详细信息。  2、去重(distinct)
  去重是指将(集合)流中重复的元素去除,通过 hashcode 和 equals 函数来判断是否是重复元素。去重操作实现了类似于 HashSet 的运算,对于对象元素流去重,需要重写 hashcode 和 equals 方法。 如果流中泛型对象使用 Lombok 插件,使用     @Data     注解默认重写了 hashcode 和 equals 方法,字段相同并且属性相同,则对象相等。更多内容可查看 Lombok 使用手册  stream.distinct();3、映射(map)
  取出流中元素的某一列,然后配合收集以形成新的集合。  stream.map(x->x.getEmpId());
  filter     和    map     操作通常结合使用,取出流中某行某列的数据,建议    先行后列     的方式定位。 Optional model = data.stream().filter(e -> e.getResId().equals(resId)).findFirst(); if (model.isPresent()) {     String itemName = model.get().getItemName();     String itemType = model.get().getItemType();     return new MainExportVo(itemId, itemName); }4、排序(sorted)
  传统的     Collectors     类中的排序支持 List 实现类中的一部分排序,使用 stream 排序,能够覆盖所有的 List 实现类。 // 按照默认字典顺序排序 stream.sorted(); // 按照工资大小排序 stream.sorted((x,y)->Integer.compare(x.getSalary(),y.getSalary()));(1)函数式接口排序
  基于 Comparator 类中函数式方法,能够更加优雅的实现对象流的排序。  // 正向排序(默认) pendingPeriod.stream().sorted(Comparator.comparingInt(ReservoirPeriodResult::getPeriod)); // 逆向排序 pendingPeriod.stream().sorted(Comparator.comparingInt(ReservoirPeriodResult::getPeriod).reversed());(2)LocalDate 和 LocalDateTime 排序
  新日期接口相比就接口,使用体验更加,因此越来越多的被应用,基于日期排序是常见的操作。  // 准备测试数据 Stream stream = Stream.of(new DateModel(LocalDate.of(2020, 1, 1)), new DateModel(LocalDate.of(2019, 1, 1)), new DateModel(LocalDate.of(2021, 1, 1)));
  正序、逆序排序  // 正向排序(默认) stream.sorted(Comparator.comparing(DateModel::getLocalDate)).forEach(System.out::println); // 逆向排序 stream.sorted(Comparator.comparing(DateModel::getLocalDate).reversed()).forEach(System.out::println);5、规约(reduce)
  对流中的元素按照一定的策略计算。终止操作的底层逻辑都是由 reduce 实现的。  (三)终止操作
  收集(collect)将流中的中间(计算)结果存储到集合中,方便后续进一步使用。为了方便对收集操作的理解,方便读者掌握收集操作,将收集分为     普通收集     和    高级收集     。 1、普通收集
  (1)收集为       List
  默认返回的类型为     ArrayList     ,可通过    Collectors.toCollection(LinkedList::new)     显示指明使用其它数据结构作为返回值容器。 List collect = stream.collect(Collectors.toList());
  由集合创建流的收集需注意:仅仅修改流字段中的内容,没有返回新类型,如下操作直接修改原始集合,无需处理返回值。  // 直接修改原始集合 userVos.stream().map(e -> e.setDeptName(hashMap.get(e.getDeptId()))).collect(Collectors.toList());
  (2)收集为       Set
  默认返回类型为     HashSet     ,可通过    Collectors.toCollection(TreeSet::new)     显示指明使用其它数据结构作为返回值容器。 Set collect = stream.collect(Collectors.toSet());2、高级收集
  (1)收集为       Map
  默认返回类型为     HashMap     ,可通过    Collectors.toCollection(LinkedHashMap::new)     显示指明使用其它数据结构作为返回值容器。
  收集为     Map     的应用场景更为强大,下面对这个场景进行详细介绍。希望返回结果中能够建立    ID     与    NAME     之间的匹配关系,最常见的场景是通过    ID     批量到数据库查询    NAME     ,返回后再将原数据集中的    ID     替换成    NAME     。 ID 到 NAME 映射 @Data public class ItemEntity {     private Integer itemId;     private String itemName; }
  准备集合数据,此部分通常是从数据库查询的数据  // 模拟从数据库中查询批量的数据 List entityList = Stream.of(new ItemEntity(1,undefinedAundefined), new ItemEntity(2,undefinedBundefined), new ItemEntity(3,undefinedCundefined)).collect(Collectors.toList());
  将集合数据转化成 ID 与 NAME 的 Map  // 将集合数据转化成ID与NAME的Map Map hashMap = entityList.stream().collect(Collectors.toMap(ItemEntity::getItemId, ItemEntity::getItemName));
  ID     与    Object     类映射 @Data public class ItemEntity {     private Integer itemId;     private String itemName;     private Boolean status; }
  将集合数据转化成 ID 与实体类的 Map  // 将集合数据转化成ID与实体类的Map Map hashMap = entityList.stream().collect(Collectors.toMap(ItemEntity::getItemId, e -> e));
  其中     Collectors     类中的    toMap     参数是函数式接口参数,能够自定义返回值。 public static  Collector> toMap(Function<? super T, ? extends K> keyMapper,                                     Function<? super T, ? extends U> valueMapper) {     return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new); }(2)分组收集
  流的分组收集操作在内存层次模拟了数据库层面的     group by     操作,下面演示流的分组操作。   Collectors   类提供了各种层次的分组操作支撑。 流的分组能力对应数据库中的聚合函数,目前大部分能在数据库中操作的聚合函数,都能在流中找到相应的能力。 // 默认使用List作为分组后承载容器 Map> hashMap = xUsers.stream().collect(Collectors.groupingBy(XUser::getDeptId));  // 显示指明使用List作为分组后承载容器 Map> hashMap = xUsers.stream().collect(Collectors.groupingBy(XUser::getDeptId, Collectors.toList()));
  映射后再分组  Map> hashMap = xUsers.stream().collect(Collectors.groupingBy(XUser::getDeptId,Collectors.mapping(XUser::getUserName,Collectors.toList())));四、Stream 拓展(一)集合与对象互转
  将对象包装成集合的形式和将集合拆解为对象的形式是常见的操作。  1、对象转集合
  返回默认类型的集合实例  /**  * 将单个对象转化为集合  *  * @param t   对象实例  * @param  对象类型  * @param  集合类型  * @return 包含对象的集合实例  */ public static > Collection toCollection(T t) {     return toCollection(t, ArrayList::new); }
  用户自定义返回的集合实例类型  /**  * 将单个对象转化为集合  *  * @param t        对象实例  * @param supplier 集合工厂  * @param       对象类型  * @param       集合类型  * @return 包含对象的集合实例  */ public static > Collection toCollection(T t, Supplier supplier) {     return Stream.of(t).collect(Collectors.toCollection(supplier)); }2、集合转对象
  使用默认的排序规则,注意此处不是指自然顺序排序。  /**  * 取出集合中第一个元素  *  * @param collection 集合实例  * @param         集合中元素类型  * @return 泛型类型  */ public static  E toObject(Collection collection) {     // 处理集合空指针异常     Collection coll = Optional.ofNullable(collection).orElseGet(ArrayList::new);     // 此处可以对流进行排序,然后取出第一个元素     return coll.stream().findFirst().orElse(null); }
  上述方法巧妙的解决两个方面的异常问题:一是集合实例引用空指针异常;二是集合下标越界异常。  (二)其它1、并行计算
  基于流式计算中的并行流,能够显著提高大数据下的计算效率,充分利用 CPU 核心数。  // 通过并行流实现数据累加 LongStream.rangeClosed(1,9999999999999999L).parallel().reduce(0,Long::sum);2、序列数组
  生成指定序列的数组或者集合。  // 方式一:生成数组 int[] ints = IntStream.rangeClosed(1, 100).toArray(); // 方式二:生成集合 List list = Arrays.stream(ints).boxed().collect(Collectors.toList());五、其它(一)新日期时间 API1、LocalDateTime// 获取当前日期(包含时间) LocalDateTime localDateTime = LocalDateTime.now(); // 获取当前日期 LocalDate localDate = localDateTime.toLocalDate(); // 获取当前时间 LocalTime localTime = localDateTime.toLocalTime();
  日期格式化  // 月份MM需要大写、小时字母需要大写(小写表示12进制) DateTimeFormatter.ofPattern(undefinedyyyy-MM-dd HH:mm:ssundefined) // 获取当前时间(字符串) String dateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern(undefinedyyyy-MM-dd HH:mm:ssundefined)); System.out.println(undefineddateTime = undefined + dateTime);2、DurationDuration duration = Duration.between(Instant.now(), Instant.now()); System.out.println(undefinedduration = undefined + duration);3、获取当前时间戳
  如下方式获取的是 13 位时间戳,单位是毫秒。  // 方式一 long now = Timestamp.valueOf(LocalDateTime.now()).getTime(); // 方式二 long now = Instant.now().toEpochMilli();(二)Optional
  在   Optional   类出现之前,     null     异常几乎折磨着每一位开发者,为了构建健壮的应用程序,不得不使用繁琐的    if     逻辑判断来回避空指针异常。解锁    Optional     类,让你编写的应用健壮性更上一层楼。 1、先判断后使用
  ifPresent     方法提供了先判断是否为空,后进一步使用的能力。 2、链式取值
  链式取值是指,层层嵌套对象取值,在上层对象不为空的前提下,才能读取其属性值,然后继续调用,取出最终结果值。有时候只关心链末端的结果状态,即使中间状态为空,直接返回空值。如下提供了一种无 if 判断,代码简介紧凑的实现方式:  Optional optional = Optional.ofNullable(tokenService.getLoginUser(ServletUtils.getRequest()))                     .map(LoginUser::getUser).map(SysUser::getUserId); // 如果存在则返回,不存在返回空 Long userId = optional.orElse(null);六、流的应用(一)列表转树
  传统方式下构建树形列表需要反复递归调用查询数据库,效率偏低。对于一棵结点较多的树,效率更低。这里提供一种只需调用一次数据库,通过流将列表转化为树的解决方式。   /**  * 列表转树  *  * @param rootList     列表的全部数据集  * @param parentId 第一级目录的父ID  * @return 树形列表  */ public List getChildNode(List rootList, String parentId) {     List lists = rootList.stream()             .filter(e -> e.getParentId().equals(parentId))             .map(IndustryNode::new).collect(toList());     lists.forEach(e -> e.setChilds(getChildNode(rootList, e.getId())));     return lists; }

自动驾驶存在降维打击吗?关键是抓住时间窗口文东篱自动驾驶公司又融资了,Momenta获得上汽集团在内的多家公司联合领投的5亿美元C轮融资。仅在今年1月,就有近30亿美元的资本涌入自动驾驶的赛道。几乎无路可耳机很大,你忍一下雷柏Ti100蓝牙降噪耳机开箱前言真蓝牙无线耳机已经开始普及的今天,更多的厂家开始拓展新的领域,已经推出了多款真蓝牙无线耳机的雷柏也顺势推出了ANC主动降噪功能的Ti100,一起开箱一瞧开箱虽然雷柏Ti100产首款V6引擎GT跑车这就是最便宜的法拉利?近日,外媒曝光了一组法拉利全新超跑的路试谍照,新车将搭载以中置V6双涡轮引擎为基础的油电混动系统,预计将成为法拉利旗下首款使用V6引擎的跑车,定位有点玛莎拉蒂MC20或者讴歌NSX新增双擎版新款丰田奕泽将6月6日上市近日,一汽丰田官方对外透露,新款奕泽IZOA系列车型将在今年6月6日正式上市,新车在细节上有所调整,并首次推出2。0L双擎混动版可选。作为参考,此前上市的新款CHR售价区间为14。电商数据采集效率开挂,从使用小捕快开始大家好上期介绍了简知系统大家有试用吗据统计我瞎哔哔的电商从业者在数据采集上每天至少花费2小时以上手动筛选数据调整样式做成表格最近创因科技推出了小捕快极大地提高了电商数据采集的效率除地表最强!一加99pro手机保护贴膜钢化膜一加9系列的似乎很值得入手。那么问题来了,一加9por适合的曲面屏的保护膜好找吗?一加9适合的曲面屏钢化膜是真的不好找,两个月前,我在网上看到较多人都在讨论一加9por这款手机。我掌阅iReader将发布10。3英寸电纸书预约价3069元根据掌阅电纸书官方微博的报道,8月27日,iReader将会发布新款电纸书。掌阅天猫旗舰店已经有了预约页面,这款10。3英寸的电纸书,搭载触控笔,预约价为3069元。据介绍,掌阅新英伟达RTX2080显卡跑分曝光领先GTX1080Ti约30老黄在昨天正式发布了基于图灵架构的QuadroRTX专业卡,基本上可以确定新一代Geforce游戏显卡使用的就是图灵架构,主要是增加了RTX处理单元,大大提升光线追踪的性能。而现在谷歌CEO确认中国审核版谷歌搜索App正在研发据CNBC报道,本周一,谷歌CEOSundarPichai承认谷歌正在开发一个中国审核版谷歌搜索App,并称能满足超过99的搜索请求。谷歌CEOSundarPichai透露了中国审一分钟看懂坚果Pro2S配置详情8月20日老罗在发布会上正式发布了坚果Pro2S,虽然本次发布会的实机演示一如既往地出现了问题,但是这款手机的亮点还是很多的,一分钟看懂坚果Pro2S配置详情。坚果Pro2S本次共智能窗帘一套500块终身可用不香吗?说起智能窗帘,大家都有一个误解。总感觉不好用,总是坏,这都是过去的老思想,传统观念。在没做智能窗帘之前,我也是这样想法。等到自己做了,发现不是这样的情况。首先介绍一下,智能窗帘是由
未来5年中国人工智能行业发展预测分析20212025年中国人工智能行业影响因素分析一有利因素(一)国家政策为人工智能产业持续加码2019年3月,国务院发布2019年政府工作报告。报告提出深化大数据人工智能等研发应用,SQL数据分析实例,春节档电影豆瓣影评数据分析今年贺岁档上映了众多电影,其中有喜剧片代表唐探3你好,李焕英,奇幻冒险片代表刺杀小说家侍神令,犯罪片人潮汹涌等,众多电影中,我最喜欢看唐探3,因为之前看过唐探1和2系列,再加之本该PowerBI数据可视化分析,春节档电影豆瓣影评数据分析本文使用图文详细地描述PowerBI软件如何连接数据库中的表,并做可视化分析,所使用的工具有NavicatPremium12和PowerBI软件,做出来的效果图如下所示。由图可以看资讯比亚迪电池涨价20以上研究称电动车用车成本超过燃油车财大气粗小米将推汽车人才激励计划金融界报道,近日,小米集团举行股东特别大会,以批准采纳XiaomiEV的股权激励计划,计划授权上限为10亿股,占XiaomiEV已发行股份总数的10大众新车全优通过?中保研最新碰撞测试成绩出炉10月28日,中保研公布了2021年第一批新车碰撞测试成绩,共涉及五个品牌的五款车型,分别是长安福特锐际长安马自达CX30上汽大众ID。4X长安UNIK以及广汽讴歌RDX。值得注意水泡车流入市场,竟加价卖给消费者在河南暴雨之后,山西和陕西部分地区也遭受到了罕见的暴雨灾害,大量土地被淹,汽车被泡在水里。河南暴雨灾情已经基本过去,但暴雨对于二手汽车市场的影响还没过去,河南暴雨中数以万计的泡水车小米汽车薪资待遇曝光上汽集团第三季度营收利润双下滑财大气粗小米汽车薪资待遇曝光日前,业内流传出一份小米汽车相关岗位的聘任书。虽然目前还无法确定这份聘任书的真实性。但从聘任书的内容来看可行度还是很高的。60万基础年薪外加100万元的宝德双路服务器PR2012P,尽显算力与存储的平衡之美对于身处信息时代的企业来说,数据的价值毋庸置疑,高效的收集存储和利用企业内外信息不仅是企业参与市场竞争需要具备的基本能力,同时也是衡量企业信息化程度的重要标准。作为领先的IT解决方人工智能构建中国双循环发展新格局2021宝德AI百城巡展双城报捷阳春布德泽,万物生光辉。人工智能构建中国双循环发展新格局2021宝德AI百城巡展正在全国紧锣密鼓的展开。3月18日,杭州和东莞两站同日圆满完成。杭州站01领导致辞会议开始,深圳市宝宝德计算机2020年业务总结暨2021年业务规划会议圆满完成1月11日走向胜利2021宝德计算机誓师大会在全体宝德人冲刺180亿一起走向胜利的誓言中圆满落下帷幕,作为誓师大会的下半场,1月1215日,宝德计算机2020年业务总结暨2021年数字化转型太难?宝德护航在数字经济发展大潮中,数字化转型已经成为当前各行各业普遍关注与发展的方向。从国家倡导的加强IT基础设施建设,推动互联网和实体经济深度融合与加快传统产业数字化和智能化等政策指导层面,