
【Java - Java 8】
文章平均质量分 82
java 8 从入门到精通
小小工匠
show me the code ,change the world
展开
-
Java Stream API - 高效数据处理的核心工具_01
Java 8 引入了Stream API,它为开发者提供了一种简洁且高效的方式来处理集合数据。Stream API 提供了丰富的操作功能,例如过滤、映射、排序、聚合等,可以极大地提高代码的可读性和可维护性,同时支持并行处理以提升性能。接下来,我们将详细介绍 Stream API 中常用的操作,包括创建流、常见的中间操作、终止操作以及一些实用的收集器。原创 2024-11-21 23:11:04 · 3212 阅读 · 0 评论 -
Java8 - Streams flatMap()
生成包含所有对象中所有书籍的流。过滤掉包含单词python的书,并收集一个Set以删除重复的书。可以将 2 levels Stream 转换成 1 level Stream.方法让你把一个流中的每个值都换成另一个流,然后把所有的流连接。,这样就可以轻松地循环 Stream 并对其进行处理。将List转换为对象流,每个对象都包含一组书籍,使用。想 将 2 级 Stream 扁平化为一级,如。处理包含多个级别的 Stream ,比如。来看个简单的功能实现,以及常犯的一些错误。或将 二维数组转换为 一维数组。原创 2023-01-02 11:27:57 · 36604 阅读 · 1 评论 -
Java8 - Streams map()
是Stream最常用的一个转换方法,它把一个Stream转换为另一个Streammap()方法用于将一个Stream的每个元素映射成另一个元素并转换成一个新的Stream;可以将一种元素类型转换成另一种元素类型。/****map()方法接收的对象是Function接口对象,它定义了一个apply()方法,负责把一个T类型转换成R类型。其中,Function的定义为/***// 将T类型转换为R: . . . . . . . . . . . . }原创 2022-12-31 22:58:41 · 35985 阅读 · 0 评论 -
Java8 - 避免代码阻塞的骚操作
文章目录Pre同步阻塞的惨案PreJava8 - 使用工厂方法 supplyAsync创建 CompletableFuture接着上面的例子假设非常不幸,无法控制 Shop 类提供API的具体实现,最终提供给你的API都是同步阻塞式的方法。这也是当你试图使用服务提供的HTTP API时最常发生的情况。你会学到如何以异步的方式查询多个商店,避免被单一的请求所阻塞,并由此提升你的“最佳价格查询器”的性能和吞吐量。同步阻塞的惨案假设你需要查询的所有商店只提供了同步API,换句话说,你有一个商家原创 2021-04-08 15:56:41 · 18155 阅读 · 10 评论 -
Java8 - 使用工厂方法 supplyAsync创建 CompletableFuture
文章目录Pre使用工厂方法 supplyAsync创建 CompletableFuturePreJava8 - 使用CompletableFuture 构建异步应用目前为止我们已经了解了如何通过编程创建 CompletableFuture 对象以及如何获取返回值,虽然看起来这些操作已经比较方便,但还有进一步提升的空间, CompletableFuture 类自身提供了大量精巧的工厂方法,使用这些方法能更容易地完成整个流程,还不用担心实现的细节。可以看到我们使用new Thread的方式,显然是原创 2021-04-08 08:45:55 · 18939 阅读 · 0 评论 -
Java8 - 使用CompletableFuture 构建异步应用
文章目录概述概述为了展示 CompletableFuture 的强大特性, 创建一个名为 best-price-finder 的应用,它会查询多个在线商店,依据给定的产品或服务找出最低的价格。这个过程中,会学到几个重要的技能。如何提供异步API如何让你使用了同步API的代码变为非阻塞代码你会了解如何使用流水线将两个接续的异步操作合并为一个异步计算操作。 比如,在线商店返回了你想要购买的商品的原始价格,并附带着一个折扣代码——最终,要计算出该商品的实际价格,你不得不访问第二个远程折扣原创 2021-04-05 23:53:36 · 17860 阅读 · 4 评论 -
Java8 - 自定义实现体会CompletableFuture的原理
文章目录CodeCodeFuture 接口 的局限性有很多,其中一个就是需要主动的去询问是否完成,如果等子线程的任务完成以后,通知我,那岂不是更好?public class FutureInAction3 { public static void main(String[] args) { Future<String> future = invoke(() -> { try { Thread.原创 2021-04-05 22:47:15 · 18065 阅读 · 8 评论 -
Java8 - Future 接口
文章目录Pre并行 VS 并发Future接口使用 Future 以异步的方式执行一个耗时的操作Pre并不希望因为等待某些服务的响应,阻塞应用程序的运行,浪费CPU时钟周期。这些场景体现了多任务程序设计的另一面。我们前面学习的分支/合并框架以及并行流是实现并行处理的宝贵工具;它们将一个操作分为多个子操作,在多个不同的核、CPU甚至是机器上并行地执行这些子操作。与此相反,如果你的意图是实现并发,而非并行,或者你的主要目标是在同一个CPU上执行几个松耦合的任务,充分利用CPU的核,让其足够忙碌,从而原创 2021-04-05 22:04:56 · 18379 阅读 · 8 评论 -
Java8 - 自定义实现体会Future的原理
文章目录自定义Future自定义Futurepackage com.artisan.java8.testFuture.customFuture;public interface CustomFutureInterface<T> { T get(); Boolean isFinished();}package com.artisan.java8.testFuture.customFuture;public interface CustomCalla原创 2021-04-05 11:37:31 · 17799 阅读 · 4 评论 -
Java8 - 一文搞定Fork/Join 框架
文章目录概述RecursiveTask概述分支/合并框架的目的是以递归方式将可以并行的任务拆分成更小的任务,然后将每个子任务的结果合并起来生成整体结果。它是 ExecutorService 接口的一个实现,它把子任务分配给线程池(称为 ForkJoinPool )中的工作线程。RecursiveTask...原创 2021-03-27 21:33:04 · 17631 阅读 · 0 评论 -
Java 8 - 正确高效的使用并行流
文章目录Pre正确使用并行流,避免共享可变状态PreJava 8 - 并行流计算入门正确使用并行流,避免共享可变状态错用并行流而产生错误的首要原因,就是使用的算法改变了某些共享状态。下面是另一种实现对前n个自然数求和的方法,但这会改变一个共享累加器:public static long sideEffectSum(long n) { Accumulator accumulator = new Accumulator(); LongStream.rangeClosed(1, n).forE原创 2021-03-25 22:56:28 · 17763 阅读 · 9 评论 -
Java 8 - 并行流计算入门
文章目录Pre什么是并行流DemoPre我们已经看到了新的 Stream 接口可以以声明性方式处理数据集,无需显式实现优化来为数据集的处理加速。到目前为止,最重要的好处是可以对这些集合执行操作流水线,能够自动利用计算机上的多个内核。在Java 7之前,并行处理数据集合非常麻烦。第一,你得明确地把包含数据的数据结构分成若干子部分。第二,你要给每个子部分分配一个独立的线程。第三,你需要在恰当的时候对它们进行同步来避免不希望出现的竞争条件,等待所有线程完成,最后把这些部分结果合并起来Java原创 2021-03-23 23:40:05 · 18236 阅读 · 0 评论 -
Java 8 - 自定义Collector
文章目录PreCollector接口声明的方法理解 Collector接口中声明的方法1.建立新的结果容器: supplier 方法2.将元素添加到结果容器: accumulator 方法3.对结果容器应用最终转换: finisher 方法4.合并两个结果容器: combiner 方法5. characteristics 方法PreCollector 接口包含了一系列方法,为实现具体的归约操作(即收集器)提供了范本。我们已经看过了 Collector 接口中实现的许多收集器,例如 toList 或原创 2021-03-18 22:53:18 · 17933 阅读 · 0 评论 -
Java 8 - 收集器Collectors_实战
文章目录原创 2021-03-16 23:55:16 · 16955 阅读 · 4 评论 -
Java 8 - Optional实战
文章目录PrePreJava 8 - Optional全解相信你已经了解,有效地使用 Optional 类意味着你需要对如何处理存在缺失值进行全面的反思。这种反思不仅仅限于你曾经写过的代码,更重要的可能是,你如何与原生Java API实现共存共赢。实际上,我们相信如果 Optional 类能够在这些API创建之初就存在的话,很多API的设计编写可能会大有不同。为了保持后向兼容性,我们很难对老的Java API进行改动,让它们也使用Optional ,但这并不表示我们什么也做不了。你可以在自己的代码原创 2021-03-14 23:11:18 · 17347 阅读 · 3 评论 -
Java 8 - CompletableFuture组合式异步编程
文章目录PrePre原创 2021-03-14 15:59:38 · 17016 阅读 · 2 评论 -
Java 8 - Optional全解
文章目录在Optional出现之前经常遇到的空指针异常采用防御式减少NullPointerException (深度质疑)null-安全的第二种尝试(过多的退出语句)Optional的介绍以及API的详解Optional之flatMap,综合练习,Optional源码剖析在Optional出现之前经常遇到的空指针异常NullPointerException【Person / Car / Insurance 的数据模型】public class Person { private Car car;原创 2021-03-14 10:51:25 · 17859 阅读 · 1 评论 -
Java 8 - 收集器Collectors_分区partitioningBy
文章目录PrePre分区是分组的特殊情况:由一个谓词(返回一个布尔值的函数)作为分类函数,它称分区函数 。分区函数返回一个布尔值,这意味着得到的分组 Map 的键类型是 Boolean ,于是它最多可以分为两组—— true 是一组, false 是一组举个例子: 把菜单按照素食和非素食分开 Map<Boolean, List<Dish>> collect = menu.stream().collect(partitioningBy(Dish::isVege原创 2021-03-13 15:47:05 · 17622 阅读 · 0 评论 -
Java 8 - 收集器Collectors_分组groupingBy
文章目录Pre第二个例子Pre来看个小例子: 把菜单中的菜按照类型进行分类,有菜的放一组,有肉的放一组,其他的都放另一组。Map<Dish.Type, List<Dish>> collect = menu.stream().collect(groupingBy(Dish::getType));用 Collectors.groupingBy 工厂方法返回的收集器就可以轻松地完成这项任务。这里,给 groupingBy 方法传递了一个 Function (以方法引用的形式原创 2021-03-12 22:26:02 · 19995 阅读 · 1 评论 -
Java 8 - 收集器Collectors_归约和汇总
文章目录Pre查找流中的最大值和最小值Pre在需要将流项目重组成集合时,一般会使用收集器( Stream 方法 collect的参数)。再宽泛一点来说,但凡要把流中所有的项目合并成一个结果时就可以用。这个结果可以是任何类型。 public static List<Dish> menu = Arrays.asList( new Dish("pork", false, 800, Dish.Type.MEAT), new Dish("bee原创 2021-03-12 01:03:51 · 17291 阅读 · 1 评论 -
Java 8 - 收集器Collectors
文章目录Pre简介Pre我们前面学到了,流可以用类似于数据库的操作帮助你处理集合。它们支持两种类型的操作:中间操作(如 filter 或 map )终端操作(如 count 、 findFirst 、 forEach 和 reduce )中间操作可以链接起来,将一个流转换为另一个流。这些操作不会消耗流,其目的是建立一个流水线。与此相反,终端操作会消耗流,以产生一个最终结果,例如返回流中的最大元素。它们通常可以通过优化流水线来缩短计算时间。前面使用过了collect 终端操作了原创 2021-03-11 22:49:42 · 17182 阅读 · 1 评论 -
Java 8 - 数值流Numberic Stream
文章目录Pre附PreJava 8 - Stream流骚操作解读2_归约操作操作了reduce, 使用 reduce 方法计算流中元素的总和.来看个例子 // 菜单中的热量求和 public static Integer sumCal(List<Dish> dishes){ return dishes.stream().map(Dish::getCalories) .reduce(0,Integer::sum);原创 2021-03-10 21:58:58 · 17149 阅读 · 0 评论 -
Java 8 - Stream实战
文章目录习题附 Trader & Transaction习题(1) 找出2011年发生的所有交易,并按交易额排序(从低到高)。-(2) 交易员都在哪些不同的城市工作过?-(3) 查找所有来自于剑桥的交易员,并按姓名排序。-(4) 返回所有交易员的姓名字符串,按字母顺序排序。-(5) 有没有交易员是在米兰工作的?-(6) 打印生活在剑桥的交易员的所有交易额。-(7) 所有交易中,最高的交易额是多少?-(8) 找到交易额最小的交易附 Trader & Tran原创 2021-03-09 00:11:35 · 17750 阅读 · 12 评论 -
Java 8 - Stream流骚操作解读2_归约操作
文章目录Pre规约元素求和最大值和最小值PreJava 8 - Stream流骚操作解读见到过的终端操作都是返回一个 boolean ( allMatch 之类的)、 void( forEach )或 Optional 对象( findAny 等)。也见过了使用 collect 来将流中的所有元素组合成一个 List 。我们这里将学会如何把一个流中的元素组合起来,使用 reduce 操作来表达更复杂的查询,比如“计算菜单中的总卡路里”或“菜单中卡路里最高的?是哪一个”。此类查询需要将流中所有元素原创 2021-03-08 23:06:00 · 17504 阅读 · 10 评论 -
Java 8 - Stream流骚操作解读
文章目录java.util.stream.Stream 中的 Stream 接口定义了许多操作。我们来看个例子可以分为两大类操作filter 、 map 和 limit 可以连成一条流水线collect 触发流水线执行并关闭它可以连接起来的流操作称为中间操作,关闭流的操作称为终端操作...原创 2021-03-08 11:53:15 · 17747 阅读 · 1 评论 -
Java 8 - Stream基本实例及Stream的并行处理在线程上的表现
文章目录需求Java 7及之前的实现需求需求: 输出小于400的Dish的名字 , 并按照卡路里排序Java 7及之前的实现package com.artisan.java8.stream;import com.artisan.java8.Dish;import java.util.*;import java.util.stream.Collectors;/** * @author 小工匠 * @version 1.0 * @description: TODO * @dat原创 2021-03-07 22:28:41 · 17455 阅读 · 8 评论 -
Java 8 - Lambda从兴趣盎然到索然无味
文章目录Pre常见的内置函数式接口`FunctionPreLambda表达式是以函数式接口作为基础,所以非常有必要了解一下函数式接口Java 8 - 01 优雅编程 lambda 以及 @FunctionalInterface注解一点通Java 8 - 02 Lambda ExpressionJava 8 - 03 Lambda 函数式接口Predicate & Consumer & Function & SupplierJava 8 - 04 类型检查、类型推断以及限制原创 2021-03-07 09:27:49 · 16791 阅读 · 8 评论 -
Java 8 - 时间API
文章目录Pre模拟SimpleDateFormate线程安全问题Pre并发编程-12线程安全策略之常见的线程不安全类模拟SimpleDateFormate线程安全问题package com.artisan.java8.testDate;import java.text.ParseException;import java.text.SimpleDateFormat;import java.time.*;import java.time.format.DateTimeFormatter;原创 2021-03-05 14:51:14 · 16694 阅读 · 8 评论 -
Java 8 - 07 复合 Lambda 表达式
文章目录PreComparator逆序 reversed()比较器链谓词复合Pre前面几个我们使用lambda表达式,都用的是默认的抽象方法,还记得不?事实上,许多函数式接口,比如用于传递Lambda表达式的 Comparator 、 Function 和 Predicate 都提供了允许你进行复合的方法这些函数接口中的其他方法(default方法或者static方法) 有啥用呢?在实际使用场景中,可以把多个简单的Lambda复合成复杂的表达式。 比如 可以让两个谓词之间做一个 or 操原创 2020-05-17 23:56:37 · 13916 阅读 · 0 评论 -
Java 8 - 06 Lambda 和方法引用实战
文章目录Pre第 1 步:传递代码第 2 步:使用匿名类第 3 步:使用 Lambda 表达式第 4 步:使用方法引用Pre前几篇文章,我们已经学习了行为参数化、匿名类、Lambda表达式和方法引用,实现了给工程师按照职位排序的功能enginnerlist.sort(comparing(Enginner::getJob))那我们来分解一下,看具体是怎样一步步的实现这么精简的写法的第 1 步:传递代码Java 8的API已经为你提供了一个 List 可用的 sort 方法, 这个是最难的部分原创 2020-05-17 23:23:31 · 13959 阅读 · 0 评论 -
Java 8 - 05 方法引用
文章目录Pre方法引用Pre先来看段代码 Comparator<Enginner> enginnerComparator = new Comparator<Enginner>() { @Override public int compare(Enginner o1, Enginner o2) { return o1.getJob().compareTo(o2.getJob());原创 2020-05-17 09:02:20 · 13934 阅读 · 3 评论 -
Java 8 - 04 类型检查、类型推断以及限制
文章目录Pre类型检查Pre当我们第一次提到Lambda表达式时,说它可以为函数式接口生成一个实例。然而,Lambda表达式本身并不包含它在实现哪个函数式接口的信息。为了全面了解Lambda表达式,women 应该知道Lambda的实际类型是什么 .类型检查Lambda的类型是从使用Lambda的上下文推断出来的。 上下文(比如,接受它传递的方法的参数,或接受它的值的局部变量)中Lambda表达式需要的类型称为目标类型。举个例子List<Apple> heavierThan15原创 2020-05-16 23:28:09 · 14282 阅读 · 0 评论 -
Java 8 - 03 Lambda 函数式接口Predicate & Consumer & Function & Supplier
文章目录PrePredicatePreJava 8 - 02 Lambda Expression中我们讨论了函数式接口, 函数式接口定义且只定义了一个抽象方法。因为抽象方法的签名可以描述Lambda表达式的签名。函数式接口的抽象方法的签名称为函数描述符。所以为了应用不同的Lambda表达式,我们需要一套能够描述常见函数描述符的函数式接口Java API中已经有了几个函数式接口,比如 Comparable 、 Runnable 和Callable 。Java 8 在 java.util.functi原创 2020-05-16 09:29:41 · 14198 阅读 · 1 评论 -
Java 8 - 02 Lambda Expression
文章目录PreLambda 初探Pre上一节 Java 8 - 01 优雅编程 lambda 以及 @FunctionalInterface注解一点通中有的时候使用了匿名类来表示不同的行为 ,代码比较啰嗦 List targetEngineerList6 = enginnerTest.findEnginner(enginnerList, new EnginnerFilter() { @Override public boolean getM原创 2020-05-13 00:19:45 · 13952 阅读 · 0 评论 -
Java 8 - 01 优雅编程 lambda 以及 @FunctionalInterface注解一点通
文章目录Pre为啥需要lambdalambda的妙用@FunctionalInterfacePre在软件工程中,不管你做什么,用户的需求肯定会变的,如何应对这样不断变化的需求? 理想的状态下,应该把你的工作量降到最少。 此外,类似的新功能实现起来还应该很简单,而且易于长期维护。行为参数化就是可以帮助我们处理频繁变更的需求的一种软件开发模式。简言之,它意味着拿出一个代码块,把它准备好却不去执行它。这个代码块以后可以被我的程序的其他部分调用,这意味着我可以推迟这块代码的执行。例如,我可以将代码块作为参原创 2020-05-11 00:17:48 · 14286 阅读 · 2 评论