java8新特性lambda表达式, 函数式接口以及Steam流和新的日期时间例子代码

时间:2021-08-03 19:04:14

java8新特性lambda表达式, 函数式接口以及Steam流和新的日期时间例子代码


package com.zheng;

import java.io.IOException;
import java.nio.*
import java.time.*
import java.util.*

public class Java8 {
public static void main(String[] args) {
// 1. 谓词: predicate,即一个返回Boolean值的函数

// 2. Lambda表达式:没有函数名的函数,但有参数列表,有函数主体,有返回值但没有返回语句(隐含return);可作为参数传递给方法
// 2.1 基本语法(parameters)->expression
// 2.2 基本语法(parameters)->{expression1; expression2}
// 2.3 布尔表达式 (List<String> list) -> list.isEmpty()
// 2.4 创建对象 () -> new User()
// 2.5 消费一个对象 (User u) -> System.out.println(u.getAge())
// 2.6 从一个对象选择/抽取 (String s) -> s.length()
// 2.7 组合两个值 (int x,int y) -> x*y
// 2.8 比较两个对象 (User u1,User u2) -> u1.getAge().compareTo(u2.getAge())
List<User> list1 = Arrays.asList(new User("u1", 10), new User("u2", 20), new User("u3", 30), new User("u4", 30));
list1.sort((u1, u2) -> u1.getAge().compareTo(u2.getAge()));
list1.sort(Comparator.comparing(User::getName));

// 3. 函数式接口: 只定义一个抽象方法的接口, 如java.util.Comparator和java.lang.Runnable
// 3.1 lambda表达式允许直接以内联的形式为函数式接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例
// 3.2 @FunctionalInterface注解表示将某个接口设计成一个函数式接口,如Runnable;该注解不是必须的
// 3.3 创建一个线程
Thread t = new Thread(() -> {
System.out.println("run method");
System.out.println("code");
});
t.start();
// 3.4 jdk8提供的函数式接口java.util.function.Predicate<T>,
// java.util.function.Consumer<T>, java.util.function.Function<T, R>
// 3.5 Predicate<T>定义了一个test抽象方法,接受泛型参数T对象,返回一个boolean
Predicate<List<User>> p1 = (List<User> list) -> list1.isEmpty();
System.out.println("list1是否为空: " + p1.test(list1));
IntPredicate a = (int i) -> i % 2 == 0;// LongPredicate,DoublePredicate
System.out.println("9是否能被2除尽: " + a.test(9));
// 3.6 Consumer<T>定义了一个accept抽象方法,接受泛型参数T对象,没有返回
Consumer<User> c1 = (User u) -> {
u.setAge(10);
System.out.println("设置对象的age为: " + u.getAge());
};
c1.accept(new User("u1", 20));
User u = new User("u1", 30);
setUserAge(u, (User u1) -> u1.getName().equals("u1"), (User u1) -> u1.setAge(100));
System.out.println("consumer: " + u.getAge());
// 3.7 Function<T, R>定义了一个apply抽象方法,接受泛型参数T对象,返回泛型R对象
Function<String, User> f1 = (String name) -> new User(name);
f1.apply("u2");
// 3.8 其它常用函数式接口
// Supplier<T>: ()->T, UnaryOperation<T>: T->T,
// BinaryOperation<T>: (T,T)->T, BiPredicate<L,R>: (L,R)->boolean,
// BiConsumer<L,U>: (L,U)->void, BiFunction<T,U,R>: (T,U)->R

// 4. 方法引用
Function<String, User> f2 = User::new;
f2.apply("123456");

// 5. 复合lambda表达式
// 5.1 排序后的逆序
list1.sort(Comparator.comparing(User::getName).reversed());
// 5.2 比较器链: 先按name排序后按age排序
list1.sort(Comparator.comparing(User::getName).thenComparing(User::getAge));
// 5.3 谓词复合
Predicate<User> p11 = u11 -> u11.getAge() > 10;
Predicate<User> p12 = p11.negate();// 非
Predicate<User> p13 = p12.and(u11 -> u11.getAge() < 100);// 与
Predicate<User> p14 = p13.or(u11 -> u11.isSex());// 或
// 5.4 函数复合
Function<Integer, Integer> f11 = x -> x + 1;
Function<Integer, Integer> f12 = x -> x - 1;
Function<Integer, Integer> f13 = f11.andThen(f12);

// 6. 流: 遍历数据集的高级迭代器, 可透明的并行的处理任务
// 6.1 筛选到list
List<String> list2 = list1.stream()// stream换成parallelStream可实现多线程并行处理
.filter(u6 -> u6.isSex())// 筛选
.sorted(Comparator.comparing(User::getAge).reversed())// 排序
.map(User::getName)// 提取名称
.limit(10)// 只取10个, 还有distinct(),count(),skip()等方法
.collect(Collectors.toList());// 创建list并保存数据
System.out.println(list2);
// 6.2 筛选到map,groupingBy(f)其实是groupingBy(f,toList())的缩写
Map<Integer, List<User>> map2 = list1.stream().collect(Collectors.groupingBy(User::getAge));
System.out.println(map2);
// 6.3 遍历
list2.forEach(s -> System.out.println("打印list2中的值: " + s));
map2.forEach((k, v) -> System.out.println("键: " + k + ", 值: " + v));
// 6.4 Arrays.stream(): 接受一个数组并产生一个流
List<Stream<String>> list3 = list1.stream().map(u6 -> u6.getName().split("")).map(Arrays::stream).distinct().collect(Collectors.toList());
// 6.5 flatMap得到扁平化流
List<String> list4 = list1.stream().map(u6 -> u6.getName().split("")).flatMap(Arrays::stream).distinct().collect(Collectors.toList());
System.out.println("flatMap: " + list4);
// 6.6 anyMatch,allMatch,noneMatch
System.out.println("anyMatch: " + list1.stream().anyMatch(u6 -> u6.getAge() == 10));
// 6.7 findFirst,findAny
Optional<User> o1 = list1.stream().filter(u6 -> u6.getAge() >= 200).findAny();
System.out.println("findAny: " + o1.isPresent());
// 6.8 reduce: 归约
int ageSum = list1.stream().map(User::getAge).reduce(0, Integer::sum);
// 6.9 mapToInt, mapToLong, mapToDouble
ageSum = list1.stream().mapToInt(User::getAge).sum();// 这里还有max(),min(),average()等方法
// 6.10 转换为对象流
IntStream is1 = list1.stream().mapToInt(User::getAge);
Stream<Integer> s2 = is1.boxed();
// 6.11 OptionalInt,OptionalDouble,OptionalLong
OptionalInt i1 = list1.stream().mapToInt(User::getAge).max();
i1.orElse(100);// 如果没有则提供默认值
// 6.12 数值范围 rangeClosed()
IntStream is2 = IntStream.rangeClosed(1, 100);
System.out.println("rangeClosed: " + is2.count());
// 6.13 Stream.of构建流
Stream<String> s3 = Stream.of("a", "b", "c", "d", "e", "f");
s3.forEach(s33 -> System.out.println("Stream.of: " + s33));
// 6.14 由数组创建流
int sum = Arrays.stream(new int[] { 1, 2, 3, 4, 5, 6 }).sum();
System.out.println("Arrays.stream: " + sum);
// 6.15 由文件生成流
try {
Stream<String> lines = Files.lines(Paths.get("/Users/zhengyongfei/Desktop/ms.txt"), Charset.defaultCharset());
System.out.println(lines.count());
} catch (IOException e) {
e.printStackTrace();
}
// 6.16 创建无限流 iterate , generate
Stream.iterate(0, n -> n + 2).limit(10).forEach(System.out::println);
Stream.generate(Math::random).limit(10).forEach(System.out::println);
// 6.17 joining
String str1 = list1.stream().map(User::getName).collect(Collectors.joining());
System.out.println(str1);
String str2 = list1.stream().map(User::getName).collect(Collectors.joining(", "));
System.out.println(str2);
// 6.18 多级分组
Map<Integer, Map<String, List<User>>> map3 = list1.stream().collect(Collectors.groupingBy(User::getAge, Collectors.groupingBy(User::getName)));
System.out.println("多级分组: " + map3);
// 6.19 按子组收集数据,还包括Collectors的maxBy,summingInt,summingDouble等方法
Map<Integer, Long> map4 = list1.stream().collect(Collectors.groupingBy(User::getAge, Collectors.counting()));
System.out.println("分组,counting: " + map4);
Map<String, Optional<User>> map5 = list1.stream().collect(Collectors.groupingBy(User::getName, Collectors.maxBy(Comparator.comparingInt(User::getAge))));
System.out.println("分组,maxby: " + map5);
// 6.20 生成set
Map<Integer, Set<User>> map6 = list1.stream().collect(Collectors.groupingBy(User::getAge, Collectors.toCollection(HashSet::new)));
System.out.println("分组,set: " + map6);
// 6.21 分区函数: 分区函数返回一个boolean值,即分组map的键类型是boolean,也即被分为两组-true一组,false一组
Map<Boolean, List<User>> map7 = list1.stream().collect(Collectors.partitioningBy((User u7) -> u7.getAge() > 20));
System.out.println("分区函数: " + map7);

// 7. java8新的日期和时间api: LocalDate,LocalTime,Instant,Duration,Period
// 7.1 LocalDate
LocalDate date = LocalDate.of(2017, 3, 15);
int year = date.getYear();
Month month = date.getMonth();
int day = date.getDayOfMonth();
DayOfWeek dow = date.getDayOfWeek();
int lengthOfMonth = date.lengthOfMonth();
date = LocalDate.now();// 当前日期
date = LocalDate.parse("2017-03-15");
// 7.2 LocalTime
LocalTime time = LocalTime.of(22, 27, 32);
int hour = time.getHour();
int minute = time.getMinute();
int second = time.getSecond();
time = LocalTime.parse("22:27:32");
// 7.3 LocalDateTime
LocalDateTime dt = LocalDateTime.of(2017, 3, 15, 22, 27, 32);
dt = LocalDateTime.of(date, time);
dt = date.atTime(22, 27, 32);
dt = date.atTime(time);
dt = time.atDate(date);
// 7.4 Duration: 以秒和纳秒来衡量时间长短
Duration d1 = Duration.between(LocalDateTime.now(), LocalDateTime.of(2017, 11, 6, 22, 27, 32));
System.out.println("两个时间相差的秒数: " + d1.getSeconds());
// 7.5 Period: 以年/月/日来衡量时间长短
Period pd1 = Period.between(LocalDate.now(), LocalDate.of(2017, 11, 6));
System.out.println("相差的年/月/日: " + pd1.getYears() + "/" + pd1.getMonths() + "/" + pd1.getDays());
// 7.6 使用TemporalAdjuster
LocalDate date2 = date.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY));// 下周一
date2 = date.with(TemporalAdjusters.lastDayOfMonth());// 本月最后一天

// 8. 其它新加入的api
// 8.1 emptyList
List<User> list8 = Collections.emptyList();
// 8.2 map新增的方法
Map<Integer, String> map8 = new HashMap<>();
System.out.println(map8.getOrDefault(1, "abc"));// 如果不存在键,则返回默认值abc

}

public static void setUserAge(User u, Predicate<User> p1, Consumer<User> c1) {
if (p1.test(u)) {
c1.accept(u);
}
}

}

class User {
public String name;
public Integer age;
public boolean sex = true;

public User() {
super();
}

public User(String name) {
super();
this.name = name;
}

public User(String name, int age) {
super();
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

public boolean isSex() {
return sex;
}

public void setSex(boolean sex) {
this.sex = sex;
}

@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}

}