-
2021-12-28 13:44:12
jdk1.8新特性知识点:
- Lambda表达式
- 函数式接口
- *方法引用和构造器调用
- Stream API
- 接口中的默认方法和静态方法
- 新时间日期API
更多相关内容 -
jdk1.8新特性
2018-03-13 11:30:56JDK1.8新特性简介剖析,仅做参考,希望大家相互学习 作为Comparator 和Runnable早期的证明,在JDK中已经定义的接口恰巧作为函数接口而与lambdas表达式兼容。同样方式可以在你自己的代码中定义任何函数接口或第三方... -
Jdk1.8特性.md
2021-09-28 14:30:28Jdk1.8特性.md -
尚硅谷JDK1.8 新特性 培训PPT
2018-05-15 11:02:14视频教程地址:http://www.gulixueyuan.com/course/56 -
JDK1.8新特性:JDK1.8究竟有那些新特性呢
2021-04-12 20:31:02JDK1.8新特性:JDK1.8究竟有那些新特性呢 JDK1.8概述 JDK1.8,又称之为Java 8(我习惯叫它为JDK1.8,后续统一叫做JDK1.8),是Java语言开发的一个主要版本。Oracle公司于2014年3月18日发布,它支持函数式编程,新的...JDK1.8新特性:JDK1.8究竟有那些新特性呢
JDK1.8概述
JDK1.8,又称之为Java 8(我习惯叫它为JDK1.8,后续统一叫做JDK1.8),是Java语言开发的一个主要版本。Oracle公司于2014年3月18日发布,它支持函数式编程,新的JavaScript引擎,新的日期API,新的Stream API等。
JDK1.8相比1.7之前版本,有以下几方面的优化:
速度更快;
代码更少(Lambda表达式);
强大Stream API;
便于并行;
最大化减少空指针异常(OPtional类)。
举例如下,JDK1.8的特性是不是与众不同。
package com.xcbeyond.study.jdk8; import org.junit.Test; import java.util.Arrays; import java.util.List; /** * JDK1.8新特性 * @Auther: xcbeyond * @Date: 2019/11/27 0027 23:53 */ public class Java8Test { @Test public void java8Example() { // 定义一个整型list,对其进行遍历 Integer[] numArray={1,2,3,4,5,6,7,8}; List<Integer> numList= Arrays.asList(numArray); /** * 方式1:常规foreach */ for (int num : numList) { System.out.println(num); } /** * 方式2:JDK1.8 新特性写法(Lambda表达式) * 代码量是不是少了很多 */ numList.forEach((num) -> System.out.println(num)); } }
新特性
JDK1.8新增了非常多的特性,本专题主要讨论以下几个:
Lambda表达式:Lambda允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
方法引用:方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
默认方法:默认方法就是一个在接口里面有了一个实现的方法。
新工具:新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。
Stream API:新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
Date Time API:加强对日期与时间的处理。
Optional类:Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
Nashorn,JavaScript引擎:JDK1.8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。Lambda 表达式的结构
一个 Lambda 表达式可以有零个或多个参数
参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同
所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
空圆括号代表参数集为空。例如:() -> 42
当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
Lambda 表达式的主体可包含零条或多条语句
如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空Lambda 表达式重要特征
可选类型声明 - 无需声明参数的类型。编译器可以从该参数的值推断。
可选圆括号参数 - 无需在括号中声明参数。对于多个参数,括号是必需的。
可选大括号 - 表达式主体没有必要使用大括号,如果主体中含有一个单独的语句。
可选return关键字 - 编译器会自动返回值,如果主体有一个表达式返回的值。花括号是必需的,以表明表达式返回一个值。
小试牛刀
new Thread(new Runnable() { @Override public void run() { System.out.println("我是传统的写法"); } }).start(); //------------------------------------------------------------ new Thread(() -> System.out.println("我是Lambda的写法")).start();
输出结果
Stream
Stream是一组用来处理数组,集合的API。
1.1 特性
不是数据结构,没有内部存储。
不支持索引访问。
延迟计算
支持并行
很容易生成数据或集合
支持过滤,查找,转换,汇总,聚合等操作。
1.2 运行机制
Stream分为源source,中间操作,终止操作。流的源可以是一个数组,集合,生成器方法,I/O通道等等。
一个流可以有零个或多个中间操作,每一个中间操作都会返回一个新的流,供下一个操作使用,一个流只会有一个终止操作。
Stream只有遇到终止操作,它的源才会开始执行遍历操作。
1.1 Stream的创建
1.通过数组,Stream.of()
2.通过集合
3.通过Stream.generate方法来创建
4.通过Stram.iterate方法
5.其他APIimport java.util.Arrays; import java.util.List; import java.util.stream.IntStream; import java.util.stream.Stream; public class CreateStream { //通过数组,Stream.of() static void gen1(){ String[] str = {"a","b","c"}; Stream<String> str1 = Stream.of(str); } //通过集合 static void gen2(){ List<String> strings = Arrays.asList("a", "b", "c"); Stream<String> stream = strings.stream(); } //通过Stream.generate方法来创建 static void gen3(){ //这是一个无限流,通过这种方法创建在操作的时候最好加上limit进行限制 Stream<Integer> generate = Stream.generate(() -> 1); generate.limit(10).forEach(x -> System.out.println(x)); } //通过Stram.iterate方法 static void gen4(){ Stream<Integer> iterate = Stream.iterate(1, x -> x +1); iterate.forEach(x -> System.out.println(x)); } //其他API static void gen5(){ String str = "abc"; IntStream chars = str.chars();## 标题 chars.forEach(x -> System.out.println(x)); } }
日期和时间
- Instant 本质上是一个数字时间戳。可以从a中检索当前的Instant Clock。这对于某个时间点的日志记录和持久性非常有用。
- LocalDateTime 存储日期和时间。这会存储类似’2010-07-23T15:47:25.890’的日期时间。
- .ZonedDateTime 使用时区存储日期和时间。如果您想要考虑到日期和时间的准确计算ZoneId,例如“欧洲/巴黎”,这将非常有用。在可能的情况下,建议使用没有时区的更简单的类。时区的广泛使用往往会给应用程序增加相当大的复杂性
- LocalTime 没有日期存储时间。存储像’11:30’这样的时间,可用于存储开盘或收盘时间。
- Instant 本质上是一个数字时间戳。可以从a中检索当前的Instant Clock。这对于某个时间点的日志记录和持久性非常有用。
其他类型
- Month 用来存储一个月。这样可以隔离单个月份,例如“DECEMBER”。
- DayOfWeek 用来存储一个星期的日子。这样可以隔离存储一个星期几,例如“星期二”
- Year 用来存储一年。这样可以隔离一年,例如’2010’。
- YearMonth 用来存储年加月份的时间。这会存储一年和一个月,例如“2010-12”,并可用于信用卡到期。
- MonthDay 用来存储月份和日子。它存储月份和日期,例如“12-03”,可用于存储年度活动,如生日,而不存储年份。
Spring Data API
<!--java 8 time date 支持--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-java8</artifactId> <version>5.0.12.Final</version> </dependency>
MyBatis
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-typehandlers-jsr310</artifactId> <version>1.0.1</version> </dependency>
-
JDK1.8(32位和64位)正式版+JDK1.8API帮助文档
2017-12-29 20:07:58jdk1.8新特性详解:(http://www.oschina.net/translate/everything-about-java-8) JDK包含的基本组件包括: javac – 编译器,将源程序转成字节码 jar – 打包工具,将相关的类文件打包成一个文件 javadoc – ... -
【jdk1.8特性】之Function
2019-09-16 14:14:12笔者日常: 来吧,Function~ 相关声明: 本文按照以下顺序进行说明并给出简单的使用示例: 序号 接口 1 Function<T, R> 2 IntFunction<R> 3 DoubleFunction<...T...笔者日常: 来吧,Function~
相关声明:
-
本文按照以下顺序进行说明并给出简单的使用示例:
序号 接口 1 Function<T, R> 2 IntFunction<R> 3 DoubleFunction<R> 4 LongFunction<R> 5 ToIntFunction<T> 6 ToLongFunction<T> 7 ToDoubleFunction<T> 8 IntToDoubleFunction 9 IntToLongFunction 10 LongToDoubleFunction 11 LongToIntFunction 12 DoubleToIntFunction 13 DoubleToLongFunction 14 BiFunction<T, U, R> 15 ToIntBiFunction<T, U> 16 ToLongBiFunction<T, U> 17 ToDoubleBiFunction<T, U> -
先给出下文的示例中所涉及到的模型:
/** * 员工实体模型 * * @author JustryDeng * @date 2019/7/15 19:48 */ @Data @AllArgsConstructor @NoArgsConstructor @Builder public class Staff implements Serializable { /** 姓名 */ private String name; /** 年龄 */ private Integer age; /** 工号 */ private String staffNo; }
Function<T, R>:
-
R apply(T t): 输入T类型的参数,运行相关逻辑后,返回R类型的结果。
使用示例:/** * R apply(T t): 输入T类型的参数,运行相关逻辑后,返回R类型的结果。 */ @Test public void test1() { Function<String, Staff> function = x -> { Staff s = new Staff(); s.setName(x + ", 咿呀咿呀哟!"); return s; }; Staff staff = function.apply("邓某"); // 输出: 邓某, 咿呀咿呀哟! System.out.println(staff.getName()); }
-
Function<V, R> compose(Function<? super V, ? extends T> before): 由两个旧的Function得到一个新的Function。
假设: 现有式子functionC = functionB.compose(functionA),functionA 泛型为<P1, R1>, functionB泛型为<R1, R2>。
那么, 上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, R2>的functionC<P1, R2>。
使用示例:
/** * <V> Function<V, R> compose(Function<? super V, ? extends T> before):由两个旧的Function得到一个新的Function。 * * 假设:现有式子functionC = functionB.compose(functionA), * functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。 * * 那么,上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值 * 作为functionB<R1, R2>的apply方法的入参,执行 * functionB<R1, R2>的apply方法,返回一个泛型为 * <P1, R2>的functionC<P1, R2>。 */ @Test public void test2() { Function<String, Integer> functionA = x -> { Objects.requireNonNull(x, "参数不能为空"); x = x.replace(" ", ""); return x.length(); }; Function<Integer, Staff> functionB = x -> { Objects.requireNonNull(x, "参数不能为空"); Staff s = new Staff(); s.setAge(x); return s; }; Function<String, Staff> functionC = functionB.compose(functionA); Staff staff = functionC.apply(" 我 是 参 数 ! "); // 输出: Staff(name=null, age=5, staffNo=null) System.out.println(staff); }
-
Function<T, V> andThen(Function<? super R, ? extends V> after: 由两个旧的Function得到一个新的Function。
假设: 现有式子functionC = functionA.andThen(functionB),functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。
那么, 上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, R2>的functionC<P1, R2>。
注: functionA.andThen(functionB)是先执行functionA,再执行functionB;而functionA.compose(functionB)是先执行functionB,再执行functionA。
使用示例:/** * <V> Function<T, V> andThen(Function<? super R, ? extends V> after):由两个旧的Function得到一个新的Function。 * * 假设:现有式子functionC = functionA.andThen(functionB), * functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。 * * 那么,上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值 * 作为functionB<R1, R2>的apply方法的入参,执行 * functionB<R1, R2>的apply方法,返回一个泛型为 * <P1, R2>的functionC<P1, R2>。 * * 注: functionA.andThen(functionB)是先执行functionA,再执行functionB; * 而functionA.compose(functionB)是先执行functionB,再执行functionA。 */ @Test public void test3() { Function<String, Integer> functionA = x -> { Objects.requireNonNull(x, "参数不能为空"); x = x.replace(" ", ""); return x.length(); }; Function<Integer, Staff> functionB = x -> { Objects.requireNonNull(x, "参数不能为空"); Staff s = new Staff(); s.setAge(x); return s; }; Function<String, Staff> functionC = functionA.andThen(functionB); Staff staff = functionC.apply(" 我 是 参 数 ! "); // 输出: Staff(name=null, age=5, staffNo=null) System.out.println(staff); }
-
static Function<T, T> identity(): 将输入的参数进行返回,即: return t -> t。
注: 在某些情景下,使用Function.identity(),会让代码更优雅。
使用示例:/** * static <T> Function<T, T> identity(): 将输入的参数进行返回,即: return t -> t。 * * 说明: 在某些情景下,使用Function.identity(),会让代码更优雅。 */ @Test public void test4() { /* * 使用普通的lambda表达式 */ Map<Integer, String> mapOne = Stream.of("a", "ab", "abc", "abcd", "abcde").collect( Collectors.toMap(String::length, param -> param) ); // 输出: {1=a, 2=ab, 3=abc, 4=abcd, 5=abcde} System.out.println(mapOne); /* * 使用Function.identity()无疑更优雅 */ Map<Integer, String> mapTwo = Stream.of("a", "ab", "abc", "abcd", "abcde").collect( Collectors.toMap(String::length, Function.identity()) ); // 输出: {1=a, 2=ab, 3=abc, 4=abcd, 5=abcde} System.out.println(mapTwo); }
IntFunction<R>:
- R apply(int value): 入参类型必须为int, (运行相关逻辑后)返回R类型的数据。
使用示例:/** * R apply(int value): 入参类型必须为int, (运行相关逻辑后)返回R类型的数据。 */ @Test public void test5() { IntFunction<Staff> intFunction = x -> { Staff staff = new Staff(); staff.setAge(x); return staff; }; Staff res = intFunction.apply(100); // 输出: Staff(name=null, age=100, staffNo=null) System.out.println(res); }
DoubleFunction<R>:
- R apply(double value): 入参类型必须为double,(运行相关逻辑后)返回R类型的数据。
使用示例:/** * R apply(double value): 入参类型必须为double, (运行相关逻辑后)返回R类型的数据 */ @Test public void test6() { DoubleFunction<String> doubleFunction = x -> (x + "").replace(".", "_"); String res = doubleFunction.apply(10.01); // 输出: 10_01 System.out.println(res); }
LongFunction<R>:
-
R apply(long value): 入参类型必须为long, (运行相关逻辑后)返回R类型的数据。
使用示例:
/** * R apply(long value): 入参类型必须为long, (运行相关逻辑后)返回R类型的数据。 */ @Test public void test7() { LongFunction<String> longFunction = x -> (x + "").replace("4", " 8484884 ").trim(); String res = longFunction.apply(484); // 输出: 8484884 8 8484884 System.out.println(res); }
ToIntFunction<T>:
- int applyAsInt(T value): 入参类型为T,(运行相关逻辑后)返回类型必为int。
使用示例:/** * int applyAsInt(T value): 入参类型为T, (运行相关逻辑后)返回类型必为int。 */ @Test public void test8() { ToIntFunction<String> toIntFunction = x -> x == null ? 0 : x.length(); int res = toIntFunction.applyAsInt("蚂蚁呀~嘿!嘿!"); // 输出: 8 System.out.println(res); }
ToLongFunction<T>:
- long applyAsLong(T value): 入参类型为T, (运行相关逻辑后)返回类型必为long。
使用示例:/** * long applyAsLong(T value): 入参类型为T, (运行相关逻辑后)返回类型必为long。 */ @Test public void test9() { ToLongFunction<String> toLongFunction = x -> x == null ? 0 : new SecureRandom(x.getBytes()).nextLong(); long res = toLongFunction.applyAsLong("蚂蚁呀~嘿!嘿!"); // 输出: 2677168598702751372 System.out.println(res); }
ToDoubleFunction<T>:
- double applyAsDouble(T value): 入参类型为T,(运行相关逻辑后)返回类型必为double。
使用示例:/** * double applyAsDouble(T value): 入参类型为T, (运行相关逻辑后)返回类型必为double。 */ @Test public void test10() { ToDoubleFunction<Float> toDoubleFunction = x -> x == null ? 0.0 : x; double res = toDoubleFunction.applyAsDouble(123.4F); // 输出: 123.4000015258789 (注:精度问题不在本文的讨论范围内) System.out.println(res); }
IntToDoubleFunction:
- double applyAsDouble(int value): 入参类型必须为int,(运行相关逻辑后)返回类型必为double。
使用示例:/** * double applyAsDouble(int value): 入参类型必须为int, (运行相关逻辑后)返回类型必为double。 */ @Test public void test11() { IntToDoubleFunction intToDoubleFunction = x -> x + 88.8; double res = intToDoubleFunction.applyAsDouble(12300); // 输出: 12388.8 System.out.println(res); }
IntToLongFunction:
- long applyAsLong(int value): 入参类型必须为int,(运行相关逻辑后)返回类型必为long。
使用示例:/** * long applyAsLong(int value): 入参类型必须为int, (运行相关逻辑后)返回类型必为long。 */ @Test public void test12() { IntToLongFunction intToLongFunction = x -> x + 1000L; long res = intToLongFunction.applyAsLong(12345); // 输出: 13345 System.out.println(res); }
LongToDoubleFunction:
- double applyAsDouble(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为double。
使用示例:/** * double applyAsDouble(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为double。 */ @Test public void test13() { LongToDoubleFunction longToDoubleFunction = x -> x + 1000000D; double res = longToDoubleFunction.applyAsDouble(12345L); // 输出: 1012345.0 System.out.println(res); }
LongToIntFunction:
- int applyAsInt(long value): 入参类型必须为long,(运行相关逻辑后)返回类型必为int。
使用示例:/** * int applyAsInt(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为int。 */ @Test public void test14() { LongToIntFunction longToIntFunction = x -> (int)(x / 1000); int res = longToIntFunction.applyAsInt(12345L); // 输出: 12 System.out.println(res); }
DoubleToIntFunction:
- int applyAsInt(double value): 入参类型必须为double,(运行相关逻辑后)返回类型必为int。
使用示例:/** * int applyAsInt(double value): 入参类型必须为double, (运行相关逻辑后)返回类型必为int。 */ @Test public void test15() { DoubleToIntFunction doubleToIntFunction = x -> (int)x; int res = doubleToIntFunction.applyAsInt(123.45); // 输出: 123 System.out.println(res); }
DoubleToLongFunction:
- long applyAsLong(double value): 入参类型必须为double,(运行相关逻辑后)返回类型必为long。
使用示例:/** * long applyAsLong(double value): 入参类型必须为double, (运行相关逻辑后)返回类型必为long。 */ @Test public void test16() { DoubleToLongFunction doubleToLongFunction = x -> (long)x; long res = doubleToLongFunction.applyAsLong(112233.4455); // 输出: 112233 System.out.println(res); }
BiFunction<T, U, R>:
-
R apply(T t, U u): 输入T类型、U类型的参数,运行相关逻辑后,返回R类型的结果。
使用示例:/** * R apply(T t, U u): 输入T类型、U类型的参数,运行相关逻辑后,返回R类型的结果。 */ @Test public void test17() { BiFunction<Integer, String, Staff> biFunction = (x, y) -> { Staff s = new Staff(); s.setAge(x); s.setName(y); return s; }; Staff staff = biFunction.apply(25, "单身邓"); // 输出: 单身邓, 25岁! System.out.println(staff.getName() + ", " + staff.getAge() + "岁!"); }
-
BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after): 由一个旧的BiFunction以及一个旧的Function得到一个新的BiFunction<T, U, V>。
假设: 现有式子biFunctionC = biFunctionA.andThen(functionB),biFunctionA泛型为<P1, T1, R1>, functionB泛型为<R1, R2>。
那么, 上述式子的逻辑是:先运行biFunctionA<P1, T1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, T1, R2>的biFunctionC<P1, T1, R2>。
使用示例:/** * <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after): * 由一个旧的BiFunction以及一个旧的Function得到一个新的BiFunction<T, U, V>。 * * 假设:现有式子biFunctionC = biFunctionA.andThen(functionB), * biFunctionA泛型为<P1, T1, R1>, functionB泛型为<R1, R2>。 * * 那么,上述式子的逻辑是:先运行biFunctionA<P1, T1, R1>的apply方法,然后将其返回值 * 作为functionB<R1, R2>的apply方法的入参,执行 * functionB<R1, R2>的apply方法,返回一个泛型为 * <P1, T1, R2>的biFunctionC<P1, T1, R2>。 */ @Test public void test18() { BiFunction<Integer, String, Staff> biFunctionA = (x, y) -> { Staff s = new Staff(); s.setAge(x); s.setName(y); return s; }; Function<Staff, Map<String, Staff>> functionB = x -> { Map<String, Staff> map = new HashMap<>(4); map.put(x.getName(), x); return map; }; BiFunction<Integer, String, Map<String, Staff>> biFunctionC = biFunctionA.andThen(functionB); Map<String, Staff> map = biFunctionC.apply(25, "单身邓"); // 输出: {单身邓=Staff(name=单身邓, age=25, staffNo=null)} System.out.println(map); }
ToIntBiFunction<T, U>:
- int applyAsInt(T t, U u): 入参类型为T和U,(运行相关逻辑后)返回类型必为int。
使用示例:/** * int applyAsInt(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为int。 */ @Test public void test19() { ToIntBiFunction<String, Double> toIntBiFunction = (x, y) -> Integer.parseInt(x) + y.intValue(); int res = toIntBiFunction.applyAsInt("123000", 456.789); // 输出: 123456 System.out.println(res); }
ToLongBiFunction<T, U>:
- long applyAsLong(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为long。
使用示例:/** * long applyAsLong(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为long。 */ @Test public void test20() { ToLongBiFunction<String, Double> toLongBiFunction = (x, y) -> Integer.parseInt(x) + y.intValue(); long res = toLongBiFunction.applyAsLong("123000", 456.789); // 输出: 123456 System.out.println(res); }
ToDoubleBiFunction<T, U>:
- double applyAsDouble(T t, U u): 入参类型为T和U,(运行相关逻辑后)返回类型必为double。
使用示例:/** * double applyAsDouble(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为double。 */ @Test public void test21() { ToDoubleBiFunction<String, Double> toDoubleBiFunction = (x, y) -> Integer.parseInt(x) + y; double res = toDoubleBiFunction.applyAsDouble("123000", 456.789); // 输出: 123456.789 System.out.println(res); }
^_^ 如有不当之处,欢迎指正
^_^ 参考资料
《jdk api 1.8_google.CHM》^_^ 测试代码托管链接
https://github.com/JustryDeng…Jdk8Feature^_^ 本文已经被收录进《程序员成长笔记》 ,笔者JustryDeng
-
-
【jdk1.8特性】之Predicate
2019-08-19 15:34:37^_^ 如有不当之处,欢迎指正 ^_^ 参考链接 Predicate详解 - 简书 ^_^ 参考文档 《jdk api 1.8_google.CHM》 ^_^ 测试代码托管链接 https://github.com/JustryDeng…Jdk8Feature ^_^ 本文已经被收录进《程序员...Predicate简介:
Predicate是一个功能性的接口,其功能是判断某个参数是否满足表达式。相似的还有BiPredicate<T, U>(使用 test(T t, U u)方法,判断参数t、u是否满足BiPredicate实例所代表的表达式);DoublePredicate(对于基本数据类型double的Predicate);LongPredicate(对于基本数据类型int的Predicate);IntPredicate(对于基本数据类型long的Predicate)。
注:本文主要学习Predicate,学会了Predicate,那么自然就学会了BiPredicate<T, U>、DoublePredicate、
IntPredicate、LongPredicate。
Predicate学习:
-
test(T t):判断t,是否满足Predicate实例所代表的表达式。
/** * test(T t): 判断t,是否满足Predicate实例所代表的表达式 */ @Test public void test1() { // 形参x的数据类型,由Predicate<T>的泛型T指定 // 定义一个 用于判断的表达式(这里为 x >= 1) Predicate<Integer> predicate = x -> x >= 1; // 判断参数是否满足 predicate代表的表达式 boolean resultOne = predicate.test(0); boolean resultTwo = predicate.test(1); // 输出结果为: false System.out.println(resultOne); // 输出结果为: true System.out.println(resultTwo); }
运行测试类,控制台输出:
-
isEqual(Object targetRef):判断targetRef,是否与Predicate实例所代表的对象相等。
/** * isEqual(Object targetRef): 判断targetRef,是否与Predicate实例所代表的对象相等 */ @Test public void test2() { /* * 等价于: * Predicate<Object> predicate = x -> { * if (x == objA) { * return true; * } * return x.equals(objA); * }; */ Object objA = new Object(); Predicate<Object> predicate = Predicate.isEqual(objA); // 判断参数是否满足 predicate代表的表达式 boolean resultOne = predicate.test(objA); boolean resultTwo = predicate.test(null); boolean resultThree = predicate.test(new Object()); // 输出结果为: true System.out.println(resultOne); // 输出结果为: false System.out.println(resultTwo); // 输出结果为: false System.out.println(resultThree); }
运行测试类,控制台输出:
-
and(Predicate<? super T> other):对两个Predicate实例取&&,得到新的Predicate实例。
/** * and(Predicate<? super T> other): 对两个Predicate实例取&&,得到新的Predicate实例 */ @Test public void test3() { // 定义两个 用于判断的表达式 Predicate<Integer> predicateOne = x -> x >= 1; Predicate<Integer> predicateTwo = x -> x <= 2; /* * 对两个表达式取 && * * 等价于:Predicate<Integer> predicateThree = x -> x >= 1 && x <= 2; */ Predicate<Integer> predicateThree = predicateOne.and(predicateTwo); // 判断参数是否满足 predicateThree代表的表达式 boolean resultOne = predicateThree.test(0); boolean resultTwo = predicateThree.test(1); boolean resultThree = predicateThree.test(2); boolean resultFour = predicateThree.test(3); // 输出结果为: false System.out.println(resultOne); // 输出结果为: true System.out.println(resultTwo); // 输出结果为: true System.out.println(resultThree); // 输出结果为: false System.out.println(resultFour); }
运行测试类,控制台输出:
-
or(Predicate<? super T> other):对两个Predicate实例取||,得到新的Predicate实例。
/** * or(Predicate<? super T> other): 对两个Predicate实例取||,得到新的Predicate实例 */ @Test public void test4() { // 定义两个 用于判断的表达式 Predicate<Integer> predicateOne = x -> x >= 1; Predicate<Integer> predicateTwo = x -> x <= -1; /* * 对两个表达式取 || * * 等价于:Predicate<Integer> predicateThree = x -> x >= 1 || x <= -1; */ Predicate<Integer> predicateThree = predicateOne.or(predicateTwo); // 判断参数是否满足 predicateThree代表的表达式 boolean resultOne = predicateThree.test(-2); boolean resultTwo = predicateThree.test(-1); boolean resultThree = predicateThree.test(0); boolean resultFour = predicateThree.test(1); boolean resultFive = predicateThree.test(2); // 输出结果为: true System.out.println(resultOne); // 输出结果为: true System.out.println(resultTwo); // 输出结果为: false System.out.println(resultThree); // 输出结果为: true System.out.println(resultFour); // 输出结果为: true System.out.println(resultFive); }
运行测试类,控制台输出:
-
negate():对当前Predicate实例取!,得到新的Predicate实例。
/** * negate(): 对当前Predicate实例取!,得到新的Predicate实例 */ @Test public void test5() { // 定义两个 用于判断的表达式 Predicate<Integer> predicateOne = x -> x >= 1; /* * 等价于:Predicate<Integer> predicate = x -> !(x >= 1); * 等价于:Predicate<Integer> predicate = x -> x < 1; */ Predicate<Integer> predicate = predicateOne.negate(); // 判断参数是否满足 predicateThree代表的表达式 boolean resultOne = predicate.test(0); boolean resultTwo = predicate.test(1); boolean resultThree = predicate.test(2); // 输出结果为: true System.out.println(resultOne); // 输出结果为: false System.out.println(resultTwo); // 输出结果为: false System.out.println(resultThree); }
运行测试类,控制台输出:
Predicate学习完毕!
^_^ 如有不当之处,欢迎指正
^_^ 参考链接
Predicate详解 - 简书^_^ 参考文档
《jdk api 1.8_google.CHM》^_^ 测试代码托管链接
https://github.com/JustryDeng…Jdk8Feature^_^ 本文已经被收录进《程序员成长笔记》 ,笔者JustryDeng
-
-
JDK1.8新特性知识详解
2022-03-23 11:36:47jdk 1.8 新特性知识详解 -
jdk1.8特性 stream filter 的使用
2020-03-31 23:13:17} 输出结果: com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 com.example.Testjdk18,test 超级记忆 头脑风暴 超级记忆2 头脑风暴2 超级记忆3 头脑风暴3年 ----------------------- 头脑风暴3... -
JDK1.8新特性之Lambda表达式
2022-05-03 17:58:42一、JDK1.8 新特性 JDK1.8概述: JDK1.8,又称之为Java 8(我习惯叫它为JDK1.8,后续统一叫做JDK1.8),是Java语言开发的一个主要版本。Oracle公司于2014年3月18日发布,它支持函数式编程,新的JavaScript引擎,... -
JDK1.8中文文档
2018-11-26 10:06:58jdk1.8新特性 Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可。 新增lambda表达式 提供函数式接口 Java 8 允许你使用 :: 关键字来传递方法或者构造函数引用 我们可以直接在lambda... -
jdk1.8新特性 lambda表达式+实战
2021-12-28 20:15:44四、Lambda作为参数 在 jdk8 之前,接口可以作为方法参数传入,执行时必须提供接口实现类的实例。从 java8 开始,Lambda 可以作为接口方法实现,当作参数传入,无论从形式上还是实际上都省去了对象的创建。使代码... -
Jdk1.8特性lambda表达式-3 和forEach()方法
2021-04-05 22:08:49Jdk1.8特性lambda表达式-3 和forEach()方法 public class Demo3_forEach { public static void main(String[] args) { List<Person> persons= new ArrayList<Person>(){ { //匿名类初始化代码 ... -
jdk1.8新特性.doc
2020-04-01 13:23:33本文主要介绍了JDK1.8版本中的一些新特性,仅供参考。 jdk1.8新特性知识点: 1、Lambda表达式 2、函数式接口 3、方法引用和构造器调用 4、Stream API 5、接口中的默认方法和静态方法 6、新时间日期API -
jdk1.8 新特性
2018-07-27 17:43:311.8 新特性 1. 速度更快 – 红黑树 2. 代码更少 – Lambda 3. 强大的Stream API – Stream 4. 便于并行 – Parallel 5. 最大化减少空指针异常 – Optional -
jdk1.8list转map的测试类
2019-09-06 11:01:49list转map的测试类,用到jdk1.8的新特性,感觉用起来很方便 -
jdk1.8-win64bit CSDN高速下载
2018-05-11 18:23:08总的来说,JDK1.8在以下方面具有新特性: 1. 速度更快 – 红黑树 2. 代码更少 – Lambda 3. 强大的Stream API – Stream 4. 便于并行 – Parallel 5. 最大化减少空指针异常 – Optional -
JDK1.8新特性总结
2020-04-26 09:55:29之前的实习的过程中,一位有着非常丰富经验的CTO曾对我说过,代码的质量,要不断的去提升。从刚开始的CRUD,到具体的业务流程实现,在这个过程中要不断的提炼代码。... (ps,我说:1.8),你知道jdk8... -
JDK1.8新特性(超详细)
2021-02-12 10:42:07这个新特性就是为了我们使用简单的呀,所以java已经内置了一堆函数式接口了。 先来个表格整体概览一下常用的一些: 函数式接口 参数类型 返回类型 用途 Supplier 供给型 无 T 返回类型为T的对象,方法:T get() ... -
JDK 1.8 新特性(个人总结,因为面试问到被拷打)
2021-11-06 21:15:272、用匿名内部类Runnable接口作为参数开启一个线程,可以精简 3、小结,黑马JDK8新特性的b站视频 二、新增四个函数式接口,一开始觉得没啥用,后来想应该是解耦合以及实现代码复用 Supplier:生产者,有一个get方法 ... -
使用JDK1.8 特性 Optional,优雅解决NullPointException
2019-05-05 16:13:48Optional是属于JDK1.8API新增的,可以优雅解决空指针异常的问题。也可以去除掉重复的if else逻辑问题。 对着旧的代码,修改为使用Optoinal逻辑,有些例子参考网址的,这个只是我作为笔记。 Optional主要方法: ... -
通过jdk1.8特性获取两个时间相减的差值
2019-12-16 18:32:11通过jdk1.8特性获取两个时间相减的差值 public static void main(String[] args) throws InterruptedException { // LocalDate today = LocalDate.now(); // System.out.println("Today : " + today); // ... -
【Java JDK1.8新特性Lambda表达式】
2022-04-04 16:48:11Java1.8新特性Lambda表达式 -
jdk 1.8源码下载
2018-07-31 15:53:15相较于之前的jdk版本,jdk1.8加入了很多新特性,诸如Lambda表达式,函数式接口,时间的处理类等新特性,值得一提的是可以在Interface接口中加入default关键字开头的方法,里面可以写实现。这一改动算是为了增加新... -
java各种工具类收集,对象属性赋值,jdk1.8特性,json串转换 List
2019-10-10 22:47:041.将一个对象的属性值复制给另一个对象 BeanUtils.copyProperties...2.jdk1.8特性 获取类目type列表 //获取某一属性集合 List<Integer> categoryTypeList = productInfoList.stream() .map(ProductInfo:... -
JDK1.8 特性--接口默认方法和静态方法
2021-03-20 21:42:26在 JDK 之前,要在一个接口中添加一个新的抽象方法,那所有的接口实现类都要去实现这个方法,不然就会编译错误,而某些实现类根本就不需要实现这个方法也被迫要写一个空实现,改动会非常大。 所以,接口默认方法... -
jdk1.8特性总结
2020-07-29 23:00:02这里写自定义目录标题jdk1.8特性总结(便于回忆记录)(一)Lambda表达式1. 函数式编程2. lambda表达式(二) 函数式接口(三)方法引用1. 方法引用2. 构造器引用3. 数组引用(三)Stream API(四)并行流和串行流...