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 + "]"; } }