JDK8新特性概览
接口中默认方法修饰为普通方法
JDK8之前
- 变量:
public static fianl修饰 - 方法:
public abstract
JDK8开始
-
支持使用
static和default修饰,二者都可以写方法体,可以不要求子类重写 -
普通方法可以有方法体
-
抽象方法没有方法体,需要子类实现
Lambda表达式
使用Lambda表达式依赖于函数接口
-
在接口中只能有一个抽象方法
-
在函数接口中定义
Object类中的方法 -
使用默认或者静态方法
-
@FunctionalInterface标识该接口为函数接口,如:1/** 2 * 只有一个抽象方法 3 * 函数接口 4 */ 5public interface MyFunctionalInterface { 6 void get(); 7}如果在该接口上加上注解
@FunctionalInterface,则该接口为中不能再有其他抽象方法,否则报错。若是有多个抽象方法,则使用Lambda表达式的时候无法知道调用哪一个方法 -
@FunctionalInterface标识的类中可以有default方法或者Object类中的方法,如:1@FunctionalInterface 2public interface MyFunctionalInterface { 3 void get(); 4 5 default void add(){ 6 } 7 8 String toString(); 9}
Lambda表达式语法
()参数列表->分割{}方法体- 完整:
(a, b) -> {}
无参方法调用
1@FunctionalInterface
2public interface WuCanInterface {
3 void get();
4}
5
6public class Test01 {
7 public static void main(String[] args) {
8 // 匿名内部类
9 new WuCanInterface() {
10 @Override
11 public void get() {
12 System.out.println("get");
13 }
14 }.get();
15
16 // Lambda表达式
17 WuCanInterface wuCanInterface = () -> {
18 System.out.println("lambda get");
19 };
20 wuCanInterface.get();
21
22 // 精简Lambda表达式
23 // 方法体中只有一条 语句的时候,不需要写{}
24 ((WuCanInterface)() -> System.out.println("精简 lambda表达式")).get();
25 }
26}
有参方法调用
1@FunctionalInterface
2public interface YouCanInterface {
3 String get(int i, int j);
4}
5
6public class Test02 {
7 public static void main(String[] args) {
8 // 匿名内部类
9 YouCanInterface youCanInterface = new YouCanInterface() {
10 @Override
11 public String get(int i, int j) {
12 return i + "--" + j;
13 }
14 };
15 System.out.println(youCanInterface.get(1, 4));
16
17 // lambda表达式
18 YouCanInterface youCanInterface1 = (i, j) -> {
19 return i + "---" + j;
20 };
21 System.out.println(youCanInterface1.get(1, 5));
22 }
23}
Lambda表达式部分应用
集合遍历
1public class Test03 {
2 public static void main(String[] args) {
3 List<String> list = new ArrayList<>();
4 list.add("B");
5 list.add("C");
6 list.add("A");
7
8 // 匿名内部类
9 list.forEach(new Consumer<String>() {
10 @Override
11 public void accept(String s) {
12 System.out.println(s);
13 }
14 });
15
16 // lambda表达式遍历
17 list.forEach(s -> {
18 System.out.println(s);
19 });
20
21 // 更精简
22 list.forEach(System.out::println);
23 }
24}
集合排序
1public class Test04 {
2 public static void main(String[] args) {
3 List<UserEntity> userList = new ArrayList<>();
4 userList.add(new UserEntity("xiaoming", 10));
5 userList.add(new UserEntity("xiaogang", 8));
6 userList.add(new UserEntity("xiaohua", 15));
7 userList.add(new UserEntity("xiaoli", 5));
8
9 // 匿名内部类方法
10 userList.sort(new Comparator<UserEntity>() {
11 @Override
12 public int compare(UserEntity o1, UserEntity o2) {
13 return o1.getAge() - o2.getAge();
14 }
15 });
16 userList.forEach(new Consumer<UserEntity>() {
17 @Override
18 public void accept(UserEntity userEntity) {
19 System.out.println(userEntity);
20 }
21 });
22
23 // lambda表达式方法
24 userList.sort((o1, o2) -> o1.getAge() - o2.getAge());
25 userList.forEach(userEntity -> {
26 System.out.println(userEntity);
27 });
28
29 // 更精简
30 userList.sort(Comparator.comparingInt(UserEntity::getAge));
31 userList.forEach(System.out::println);
32 }
33}
线程调用
因为Runnable接口是函数接口
1public class Test05 {
2 public static void main(String[] args) {
3 // 匿名内部类
4 new Thread(new Runnable() {
5 @Override
6 public void run() {
7 System.out.println("线程名称: " + Thread.currentThread().getName() + ", 子线程");
8 }
9 }).start();
10
11 // lambda表达式
12 new Thread(() -> System.out.println("线程名称: " + Thread.currentThread().getName() + ", 子线程")).start();
13 }
14}
Stream流

- 串行流
- 并行流
1public class Test01 {
2
3 public static void main(String[] args) {
4 List<UserEntity> userList = new ArrayList<>();
5 // 创建方式有两种
6 // 第一种: 串行流
7 Stream<UserEntity> stream = userList.stream();
8
9 // 第二种:并行流
10 Stream<UserEntity> userEntityStream = userList.parallelStream();
11 }
12
13}
Stream流部分应用
List集合转map
1public class Test01 {
2
3 public static void main(String[] args) {
4 List<UserEntity> userList = new ArrayList<>();
5 userList.add(new UserEntity("xiaoming", 10));
6 userList.add(new UserEntity("xiaogang", 8));
7 userList.add(new UserEntity("xiaohua", 15));
8 userList.add(new UserEntity("xiaoli", 5));
9 userList.add(new UserEntity("xiaowang", 3));
10
11 // 创建方式有两种
12 // 第一种: 串行流
13 Stream<UserEntity> stream = userList.stream();
14
15 // 第二种:并行流
16 Stream<UserEntity> userEntityStream = userList.parallelStream();
17
18 Map<String, UserEntity> map = stream.collect(Collectors.toMap(new Function<UserEntity, String>() {
19 // 第一个泛型UserEntity是List中泛型的类型
20 // 第二个泛型String是将要转换的Map中key的类型
21 @Override
22 public String apply(UserEntity userEntity) {
23 // 该方法是key
24 return userEntity.getUsername();
25 }
26 }, new Function<UserEntity, UserEntity>() {
27 // 第一个泛型UserEntity是List中泛型的类型
28 // 第二个泛型UserEntity是将要转换的Map中value的类型
29 @Override
30 public UserEntity apply(UserEntity userEntity) {
31 // 该方法还value
32 return userEntity;
33 }
34 }));
35
36 map.forEach(new BiConsumer<String, UserEntity>() {
37 @Override
38 public void accept(String s, UserEntity userEntity) {
39 System.out.println(s + "----" + userEntity.getUsername());
40 }
41 });
42
43 // lambda表达式简化
44 Map<String, UserEntity> map2 = stream.collect(Collectors.toMap(UserEntity::getUsername, userEntity -> userEntity));
45 map.forEach((s, userEntity) -> System.out.println(s + "----" + userEntity.getUsername()));
46
47 }
48}
计算求和
1public class Test02 {
2 public static void main(String[] args) {
3 Stream<Integer> stream = Stream.of(10, 20, 40, 60, 30);
4 Optional<Integer> reduce = stream.reduce(new BinaryOperator<Integer>() {
5 @Override
6 public Integer apply(Integer num1, Integer num2) {
7 return num1 + num2;
8 }
9 });
10 System.out.println(reduce.get());
11
12 // lambda精简
13 reduce = stream.reduce(Integer::sum);
14 System.out.println(reduce.get());
15
16
17 // 对象
18 List<UserEntity> userList = new ArrayList<>();
19 userList.add(new UserEntity("xiaoming", 10));
20 userList.add(new UserEntity("xiaogang", 8));
21 userList.add(new UserEntity("xiaohua", 15));
22 userList.add(new UserEntity("xiaoli", 5));
23 userList.add(new UserEntity("xiaowang", 3));
24 Optional<UserEntity> reduceEntity = userList.stream().reduce(new BinaryOperator<UserEntity>() {
25 @Override
26 public UserEntity apply(UserEntity userEntity, UserEntity userEntity2) {
27 UserEntity reduceEntity = new UserEntity("reduce", 0);
28 reduceEntity.setAge(userEntity.getAge() + userEntity2.getAge());
29 return reduceEntity;
30 }
31 });
32 System.out.println(reduceEntity.get());
33
34 // lambda精简
35 reduceEntity = userList.stream().reduce((userEntity, userEntity2) -> {
36 UserEntity reduceEntity1 = new UserEntity("reduce", 0);
37 reduceEntity1.setAge(userEntity.getAge() + userEntity2.getAge());
38 return reduceEntity1;
39 });
40 System.out.println(reduceEntity.get());
41
42 }
43}
查找集合最值元素
1public class Test03 {
2 public static void main(String[] args) {
3 List<UserEntity> userList = new ArrayList<>();
4 userList.add(new UserEntity("xiaoming", 10));
5 userList.add(new UserEntity("xiaogang", 8));
6 userList.add(new UserEntity("xiaohua", 15));
7 userList.add(new UserEntity("xiaoli", 5));
8 userList.add(new UserEntity("xiaowang", 3));
9
10 // 最大值
11 Optional<UserEntity> max = userList.stream().max(new Comparator<UserEntity>() {
12 @Override
13 public int compare(UserEntity o1, UserEntity o2) {
14 return o1.getAge() - o2.getAge();
15 }
16 });
17 System.out.println(max.get());
18 // lambda表达式方式
19 max = userList.stream().min(Comparator.comparingInt(UserEntity::getAge));
20 System.out.println(max.get());
21
22 // 最小值
23 Optional<UserEntity> min = userList.stream().min(new Comparator<UserEntity>() {
24 @Override
25 public int compare(UserEntity o1, UserEntity o2) {
26 return o1.getAge() - o2.getAge();
27 }
28 });
29 System.out.println(min.get());
30
31 // lambda表达式方式
32 min = userList.stream().min(Comparator.comparingInt(UserEntity::getAge));
33 System.out.println(min.get());
34 }
35}
判断集合是否存在某元素
allMatch:所有元素都满足返回trueanyMatch: 只要有满足一条满足,就返回true
1public class Test04 {
2 public static void main(String[] args) {
3 List<UserEntity> userList = new ArrayList<>();
4 userList.add(new UserEntity("xiaoming", 10));
5 userList.add(new UserEntity("xiaogang", 8));
6 userList.add(new UserEntity("xiaohua", 15));
7 userList.add(new UserEntity("xiaoli", 5));
8 userList.add(new UserEntity("xiaowang", 3));
9
10 // 集合中是否存在
11 boolean xiaoming = userList.stream().anyMatch(new Predicate<UserEntity>() {
12 @Override
13 public boolean test(UserEntity userEntity) {
14 return userEntity.getUsername().equals("xiaoming");
15 }
16 });
17 System.out.println(xiaoming);
18
19 // lambda表达式形式
20 xiaoming = userList.stream().anyMatch(userEntity -> userEntity.getUsername().equals("xiaoming"));
21 System.out.println(xiaoming);
22
23 // 集合中的源素是否满足
24 xiaoming = userList.stream().allMatch(new Predicate<UserEntity>() {
25 @Override
26 public boolean test(UserEntity userEntity) {
27 return userEntity.getUsername().equals("xiaoming");
28 }
29 });
30 System.out.println(xiaoming);
31
32 // lambda表达式形式
33 xiaoming = userList.stream().allMatch(userEntity -> userEntity.getUsername().equals("xiaoming"));
34 System.out.println(xiaoming);
35
36 }
37}
过滤器
1public class Test05 {
2 public static void main(String[] args) {
3 List<UserEntity> userList = new ArrayList<>();
4 userList.add(new UserEntity("xiaoming", 10));
5 userList.add(new UserEntity("xiaogang", 8));
6 userList.add(new UserEntity("xiaohua", 15));
7 userList.add(new UserEntity("xiaoli", 5));
8 userList.add(new UserEntity("xiaowang", 3));
9 userList.add(new UserEntity("xiaogang", 27));
10
11 userList.stream().filter(new Predicate<UserEntity>() {
12 @Override
13 public boolean test(UserEntity userEntity) {
14 // 这里可以添加多个条件
15 // 如还需要年龄要求 可以直接加 && userEntity.getAge > 10
16 return userEntity.getUsername().equals("xiaogang");
17 }
18 }).forEach(new Consumer<UserEntity>() {
19 @Override
20 public void accept(UserEntity userEntity) {
21 System.out.println(userEntity.toString());
22 }
23 });
24
25 // lambda表达式
26 userList.stream().filter(userEntity -> {
27 // 这里可以添加多个条件
28 // 如还需要年龄要求 可以直接加 && userEntity.getAge > 10
29 return userEntity.getUsername().equals("xiaogang");
30 }).forEach(userEntity -> System.out.println(userEntity.toString()));
31 }
32}
limit和skip
skip:跳过n条limit:从第0条开始返回n条
可以联合使用skip和limit完成分页效果。
由于limit无法选择从第几条开始,只能限制返回几条,所以可以先使用skip跳过指定条数,再使用limit来限制需要返回的条数。
1public class Test06 {
2 public static void main(String[] args) {
3 List<UserEntity> userList = new ArrayList<>();
4 userList.add(new UserEntity("xiaoming", 10));
5 userList.add(new UserEntity("xiaogang", 8));
6 userList.add(new UserEntity("xiaohua", 15));
7 userList.add(new UserEntity("xiaoli", 5));
8 userList.add(new UserEntity("xiaowang", 3));
9 userList.add(new UserEntity("xiaogang", 27));
10
11 // 输出xiaoli和xiaowang两条记录
12 userList.stream().skip(3).limit(2).forEach(userEntity -> {
13 System.out.println(userEntity.toString());
14 });
15
16 }
17}
排序
1public class Test07 {
2 public static void main(String[] args) {
3 List<UserEntity> userList = new ArrayList<>();
4 userList.add(new UserEntity("xiaoming", 10));
5 userList.add(new UserEntity("xiaogang", 8));
6 userList.add(new UserEntity("xiaohua", 15));
7 userList.add(new UserEntity("xiaoli", 5));
8 userList.add(new UserEntity("xiaowang", 3));
9 userList.add(new UserEntity("xiaogang", 27));
10
11 userList.stream().sorted(Comparator.comparingInt(UserEntity::getAge)).forEach(System.out::println);
12
13 }
14}
并行流
利用500亿以内的数累加求和来测试
-
串行流
1public class Test08 { 2 public static void main(String[] args) { 3 Instant start = Instant.now(); 4 long sum = 0; 5 6 for (long i = 0; i < 50000000000L; i++) { 7 sum += i; 8 } 9 10 System.out.println(sum); 11 Instant end = Instant.now(); 12 13 System.out.println("【串行流】500亿累加求和用时:" + (Duration.between(start, end).toMillis())); 14 15 // 打印结果: 16 // -4378597037249509888 17 // 【串行流】500亿累加求和用时:11279 18 } 19} -
串行流
1public class Test09 { 2 public static void main(String[] args) { 3 Instant start = Instant.now(); 4 5 LongStream longStream = LongStream.rangeClosed(0, 50000000000L); 6 OptionalLong result = longStream.parallel().reduce(new LongBinaryOperator() { 7 @Override 8 public long applyAsLong(long left, long right) { 9 return left + right; 10 } 11 }); 12 13 System.out.println(result.getAsLong()); 14 Instant end = Instant.now(); 15 16 System.out.println("【并行流】500亿累加求和用时:" + (Duration.between(start, end).toMillis())); 17 18 // 打印结果 19 // -4378596987249509888 20 //【并行流】500亿累加求和用时:5416 21 } 22}采用多线程分段计算来增加计算速度。
fork join
对象判空
常用的API:
Optional.ofNullable()Optional.of()isPresent()
1public class Test01 {
2 public static void main(String[] args) {
3 String username = null;
4 // 允许传递的对象为空
5 Optional<String> optional = Optional.ofNullable(username);
6 // 代码将在这一行抛出异常
7 String getUsername = optional.get();
8 System.out.println(getUsername);
9
10 String username1 = null;
11 // 不允许传递的对象为空
12 // 代码将在这一行抛出异常
13 Optional<String> optional2 = Optional.of(username1);
14 String getUsername1 = optional.get();
15 System.out.println(getUsername1);
16
17
18 // ofNullable和isPresent联合使用
19 // 优先判断是否为空
20 String username3 = null;
21 // 允许传递的对象为空
22 Optional<String> optional3 = Optional.ofNullable(username3);
23 // 如果username3为空,则返回false,否则返回true
24 boolean isPresent = optional.isPresent();
25 System.out.println(isPresent);
26 }
27}
默认值
orElse()
1public class Test02 {
2 public static void main(String[] args) {
3 String username = null;
4 // 允许传递的对象为空
5 Optional<String> optional = Optional.ofNullable(username);
6 // 如果对象为空则使用默认值
7 String orElseUsername = optional.orElse("默认值");
8 System.out.println(orElseUsername);
9 }
10}
条件过滤
-
filter()返回值依然是
Optional对象
1public class Test03 {
2 public static void main(String[] args) {
3 String username = "测试过滤";
4 // 允许传递的对象为空
5 Optional<String> optional = Optional.ofNullable(username);
6 // 如果对象为空则使用默认值
7 Optional<String> filter = optional.filter(new Predicate<String>() {
8 @Override
9 public boolean test(String s) {
10 return s.equals("测试过滤");
11 }
12 });
13
14 // 返回的依然是一个Optional
15 // 如果过滤结束此处没有值了,这里会报错
16 System.out.println(filter.get());
17
18 // lambda简化
19 Optional<String> filter1 = optional.filter(s -> s.equals("测试过滤"));
20 System.out.println(filter1.get());
21 }
22}
案例
将给定对象一个属性字符串中的英文字符全部改成大写
1public class Test04 {
2 public static void main(String[] args) {
3 MessageEntity messageEntity = new MessageEntity("test01", "TEst01");
4 String result = Optional.ofNullable(messageEntity)
5 // messageEntity1 为前面传入的messageEntity
6 .map(messageEntity1 -> messageEntity.getMsg())
7 // message 为传入的messageEntity.getMsg()
8 .map(mesesage -> mesesage.toUpperCase(Locale.ROOT))
9 .orElse(null);
10 System.out.println(result);
11 }
12}
— END —