Java8新特性-Lambda表达式-Stream API等(学习笔记)
2020-06-05 19:20
36 查看
Java8新特性-Lambda表达式-Stream API等_尚硅谷__李贺飞
内容:
- lambda表达式(重点)
- 函数式表达式
- 方法引用与构造器引用
- Stream API(重点)
- 接口中的默认方法与静态方法
- 新实践日期API
- 其他新特性
lambda表达式(重点)
为什么使用lambda表达式是一段匿名函数,写出更加简洁的代码
// 创建集合对象 List<Employee> employees = Arrays.asList( new Employee("张三",18,9090.90), new Employee("王武",35,4567.90), new Employee("王二",45,9090.90), new Employee("李四",34,567.90), new Employee("小平",18,9090.90) );
需求:获取当前公司中员工年龄大于35的员工信息
@Test public void test4(){ List<Employee> list = filterEmployees(employees); for (Employee employee : list) { System.out.println(employee); } } // 过滤,找到满足条件的集合 public List<Employee> filterEmployees(List<Employee> employees){ List<Employee> emps = new ArrayList<>(); for (Employee emp : employees) { if (emp.getAge() >= 35){ emps.add(emp); } } return emps; }
需求1:获取当前公司中员工年龄大于35的员工信息
需求2: 获取当前公司中员工工资大于5000的员工信息
优化一:采用策略设计模式
创建一个接口MyPredicate
创建接口 MyPredicate 的实现类,用作筛选员工
@Test public void test5(){ List<Employee> list = filterEmployee(this.employees, new FilterEmployeeByAge()); for (Employee employee : list) { System.out.println(employee); } System.out.println("-----------------------"); List<Employee> list1 = filterEmployee(this.employees, new FilterEmployeeBySalary()); for (Employee employee : list1) { System.out.println(employee); } } /** * @param list 需要过滤的参数 * @param mp 过滤的方法 * @return */ public List<Employee> filterEmployee(List<Employee> list, MyPredicate<Employee> mp){ List<Employee> emps = new ArrayList<>(); for (Employee employee : list) { if (mp.test(employee)){ emps.add(employee); } } return emps; }
package com.java8.service; public interface MyPredicate<T> { boolean test(T t); }
package com.java8.service.impl; import com.java8.pojo.Employee; import com.java8.service.MyPredicate; // 根据员工的年龄,过滤Employee public class FilterEmployeeByAge implements MyPredicate<Employee> { @Override public boolean test(Employee employee) { return employee.getAge() >= 35; } }
package com.java8.service.impl; import com.java8.pojo.Employee; import com.java8.service.MyPredicate; // 根据员工的薪资,过滤Employee public class FilterEmployeeBySalary implements MyPredicate<Employee> { @Override public boolean test(Employee employee) { return employee.getSalary() > 5000; } }
优化方式二:匿名内部类
创建一个接口MyPredicate
// 优化方式二:匿名内部类 @Test public void test6(){ List<Employee> list = filterEmployee(this.employees, new MyPredicate<Employee>() { @Override public boolean test(Employee employee) { return employee.getSalary() <= 5000; } }); for (Employee employee : list) { System.out.println(employee); } } /** * @param list 需要过滤的参数 * @param mp 过滤的方法 * @return */ public List<Employee> filterEmployee(List<Employee> list, MyPredicate<Employee> mp){ List<Employee> emps = new ArrayList<>(); for (Employee employee : list) { if (mp.test(employee)){ emps.add(employee); } } return emps; }
优化方式三:lambada表达式
// 优化方式三:lambada表达式 @Test public void test7() { List<Employee> list = filterEmployee(this.employees, (e) -> e.getSalary() <= 5000); list.forEach(System.out::println); } /** * @param list 需要过滤的参数 * @param mp 过滤的方法 * @return */ public List<Employee> filterEmployee(List<Employee> list, MyPredicate<Employee> mp){ List<Employee> emps = new ArrayList<>(); for (Employee employee : list) { if (mp.test(employee)){ emps.add(employee); } } return emps; }
优化方式四:lambada表达式
// 优化方式四:lambada表达式 @Test public void test8() { employees.stream() .filter((e)->e.getSalary() >= 5000) .limit(2) .forEach(System.out::println); System.out.println("---------"); employees.stream() .map(Employee::getName) .forEach(System.out::println); }lambada表达式的基础语法
package com.java8.demo; import com.java8.service.Myfun; import org.junit.Test; import java.util.Comparator; import java.util.function.Consumer; /** * 一、Lambda表达式的基本语法:-> 箭头操作符将lambda表达式分成两部分 * * 左侧:lambda 表达式的参数列表 * 右侧:lambda 表达式中所需要执行的功能,即 lambda体 * * 语法格式一:无参数,无返回值 * () -> System.out.println("Hello, lambda") * 语法格式二:有一个参数,无返回值 * (c) -> System.out.println(c) * 语法格式三:若只有一个参数,小括号可以省略不写 * (c) -> System.out.println(c) * 语法格式四:有两个以上的参数,有返回值,并且lambda体中有多条语句 * Comparator<Integer> com = (x,y) -> { * System.out.println("函数式接口"+x+y); * return Integer.compare(x, y); * }; * 语法格式五:若lambda体中只有一条语句,return 和 大括号 都可以省略不写 * Comparator<Integer> com1 =(x,y) -> Integer.compare(x,y); * 语法格式六:lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型, * * 二、Lambda表达式 需要函数是接口的支持 * 函数式接口:接口中只有一个抽象方法的接口,称为函数式接口,可以使用@FunctionInterface 修饰 * 可以检查是否是函数式接口 * */ public class TestLambda2 { @Test public void test1(){ // 注意事项: 在局部内部类中应用同级别的局部变量时,该变量定义为final // 1.8之前需要自己手动写final,1.8之后默认 final int num = 0; Runnable r = new Runnable() { @Override public void run() { System.out.println("Hello, lambda" + num); } }; r.run(); System.out.println("------------"); Runnable r1 = () -> System.out.println("Hello, lambda"); r1.run(); } @Test public void test2(){ Consumer<String> con = (c) -> System.out.println(c+"mii"); con.accept("你好"); } @Test public void test3(){ Comparator<Integer> com = (x,y) -> { System.out.println("函数式接口"+x+y); // return x > y ? x : y; return Integer.compare(x, y); }; Comparator<Integer> com1 =(x,y) -> Integer.compare(x,y); System.out.println(com.compare(1, 0)); } // 需求:对一个数进行计算 @Test public void test4(){ Integer operation = operation(100, (x) -> x * x); System.out.println(operation); } public Integer operation(Integer num, Myfun mf){ return mf.getValue(num); } }
package com.java8.service; @FunctionalInterface public interface Myfun { Integer getValue(int i); }lambda表达式的练习
package com.java8.demo; import com.java8.pojo.Employee; import com.java8.service.MyLong; import com.java8.service.MyString; import org.junit.Test; import java.util.Arrays; import java.util.Collections; import java.util.List; public class TestLambda3 { List<Employee> employees = Arrays.asList( new Employee("张三",18,9090.90), new Employee("王武",35,4567.90), new Employee("王二",45,9090.90), new Employee("李四",34,567.90), new Employee("小平",18,9090.90) ); @Test public void test1(){ Collections.sort(employees, (e1,e2)->{ if (e1.getAge() == e2.getAge()){ return e1.getName().compareTo(e2.getName()); }else { return Integer.compare(e1.getAge(),e2.getAge()); } }); for (Employee employee : employees) { System.out.println(employee); } } @Test public void test2(){ String a = operation("adfd", (s) -> s.toUpperCase()); System.out.println(a); String a1 = operation("adfduibvc", (s) -> s.substring(2,5)); System.out.println(a1); } public String operation(String str, MyString ms){ return ms.getValue(str); } @Test public void test3(){ operation2(100L,200L,(x,y)->x+y); } public void operation2(Long l1, Long l2,MyLong<Long,Long> ml){ System.out.println(ml.getValue(l1, l2)); } }
四大内置核心函数式接口
package com.java8.demo; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; /** * java8 内置的四大核心函数式接口 * Consumer<T>:消费性接口 * void accept(T,t); * Supplier<T>: 供给型接口 * T get(); * Function<T,R>:函数型接口 * R apply(T,t); * Predicate<T>:断言型接口 * boolean test(T t); */ public class Testlambda4 { // Predicate<T>:断言型接口 // 将满足条件的字符串放入集合中去 @Test public void test4(){ List<String> list = Arrays.asList("huhu","lplp","lplko","kokookok","kokokoll"); List<String> strings = filterStr(list, (str) -> str.length() > 4); for (String string : strings) { System.out.println(string); } } public List<String> filterStr(List<String> list, Predicate<String> pre){ List<String> strList = new ArrayList<>(); for (String s : list) { if (pre.test(s)){ strList.add(s); } } return strList; } // Function<T,R>:函数型接口 // 需求:用于处理字符串 @Test public void test3(){ String newStr = strHandler("strdcsnvns ", (str) -> str.trim()); System.out.println(newStr); } public String strHandler(String str, Function<String,String> fun){ return fun.apply(str); } // Supplier<T>: 供给型接口 // 需求:产生指定个数的整数,并放到集合当中去 @Test public void test2(){ List<Integer> numList = getNumList(10, () -> (int) (Math.random() * 10)); for (Integer integer : numList) { System.out.println(integer); } } public List<Integer> getNumList(int num, Supplier<Integer> sup){ List<Integer> list = new ArrayList<>(); for (int i = 0; i < num ; i++) { list.add(sup.get()); } return list; } // Consumer<T>:消费性接口 @Test public void test1(){ happy(100d,(x) -> System.out.println(x)); } public void happy(Double d, Consumer<Double> con){ con.accept(d); } }
方法引用与构造器引用(没有听懂)
Stream流
流都是对数据的操作
首先把数据源转化成流,中间的操作处理,变成一个全新的和之前无关的流。
是数据的渠道,用于操作数据源(集合,数组等)所生成的元素序列,“集合讲的是数据,流讲的是计算”
Stream 自己不会存储元素。
Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才知性。
创建Stream流
package com.java8.demo; import com.java8.pojo.Employee; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; /** * 一、Stream 的基本操作 * 1。创建Stream * * 2。中间操作 * * 3。终止操作(终端操作) */ public class TestStreamAPI1 { // 创建Stream @Test public void test1(){ // 1.可以通过Collection 系列集合提供的stream() 或者 parallelStream() List<String> list = new ArrayList<>(); Stream<String> stream1 = list.stream(); // 2. 通过Arrays 中的静态方法stream() 获取数组流 Employee[] emps = new Employee[10]; Stream<Employee> stream2 = Arrays.stream(emps); // 3. 通过Stream 类中的静态方法of() Stream<String> stream3 = Stream.of("aaa", "bbb", "ccc"); // 4. 创建无限流 Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 2); stream4.limit(4).forEach(System.out::println); // 5.生成 Stream.generate(()->Math.random()) .limit(5) .forEach(System.out::println); } }stream的中间操作_筛选与切片
多个中间可以连接起来形成一个流水线,除非流水线上的触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性操作”。
package com.java8.demo.stream; import com.java8.pojo.Employee; import org.junit.Test; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.stream.Stream; /** * 一、Stream 的基本操作 * 1。创建Stream * * 2。中间操作 * * 3。终止操作(终端操作) */ public class TestStreamAPI2 { /** * 中间操作: * * 筛选与切片 * 1、filter——过滤Lambda , 从流中排除某些元素。 * 2、limit——截断,使其元素不超过给定数量。 * 3、skip(n) —— 跳越,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补 * 4、distinct——除重,通过流所生成元素的 hashCode() 和 equals() 去除重复元素 * 需要注意的一点: * 只有当做终止操作时,所有的中间操作会一次性的全部执行,称为“惰性求值” */ List<Employee> employees = Arrays.asList( new Employee("张三",18,9090.90), new Employee("张三",34,9090.90), new Employee("张三",18,9090.90), new Employee("王武",35,4567.90), new Employee("王二",45,9090.90), new Employee("李四",34,567.90), new Employee("小平",18,9090.90) ); // 内部迭代:迭代操作由Stream API完成 @Test public void test1(){ // 中间操作:不会执行任何操作 Stream<Employee> stream = employees.stream() .filter((e) -> { System.out.println("Stream API 中间操作"); return e.getAge() > 30; }); // 终止操作:一次性执行全部内容,即"惰性求值" stream.forEach(System.out::println); } // 外部迭代 @Test public void test2(){ Iterator<Employee> iterator = employees.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } } @Test public void test3(){ employees.stream() .filter((employee) ->{ System.out.println("duanlu"); return employee.getAge()>30; }) .limit(2) .forEach(System.out::println); } @Test public void test4(){ employees.stream() .filter((employee)->{ System.out.println("nihao"); return employee.getAge()>=30; }) .skip(1) .forEach(System.out::println); } @Test public void test5(){ employees.stream() .distinct() .forEach(System.out::println); } }stream映射
package com.java8.demo.stream; import com.java8.pojo.Employee; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; public class TestStreamAPI3 { /** * 映射 map——接收 Lambda , 将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。 flatMap——接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流 注释:相当于list集合的 add 和 addAll 的区别 */ List<Employee> employees = Arrays.asList( new Employee("张三",18,9090.90), new Employee("王武",35,4567.90), new Employee("王二",45,9090.90), new Employee("李四",34,567.90), new Employee("小平",18,9090.90) ); @Test public void test1(){ List<String> list = Arrays.asList("aaa","bbb","ccc"); list.stream() .map((s)->s.toUpperCase()) .forEach(System.out::println); System.out.println("------------"); employees.stream() .map(Employee::getName) // 流中的每一个元素都用到这个函数上 .forEach(System.out::println); System.out.println("------------"); // map本身得到的就是一个Stream,而执行方法后得到的还是流,在流中得到Character Stream<Stream<Character>> streamStream = list.stream() .map(TestStreamAPI3::filterCharacter); // 提取的参数"aaa",调用这个方法 {{a,a,a},{b,b,b}} // 遍历 -- 第一次遍历得到的还是流, streamStream.forEach((sm) -> { sm.forEach(System.out::println); } ); System.out.println("------------"); list.stream() .flatMap(TestStreamAPI3::filterCharacter) // {a,a,a,b,b,b} .forEach(System.out::println); } // 该方法,用于接收字符安传,并返回一个流 public static Stream<Character> filterCharacter(String str){ List<Character> list = new ArrayList<>(); for (Character ch : str.toCharArray()) { list.add(ch); } return list.stream(); } }stream排序
package com.java8.demo.stream; import com.java8.pojo.Employee; import org.junit.Test; import java.util.Arrays; import java.util.List; public class TestStreamAPI4 { /** * 排序 * sorted() -- 自然排序 * sorted(Comparator com) -- 定制排序 */ List<Employee> employees = Arrays.asList( new Employee("张三",18,9090.90), new Employee("张三",34,9090.90), new Employee("张三",18,9090.90), new Employee("王武",35,4567.90), new Employee("王二",45,9090.90), new Employee("李四",34,567.90), new Employee("小平",18,9090.90) ); @Test public void test1(){ List<String> list = Arrays.asList("ccc","aaa","bbb","ddd"); list.stream() .sorted() .forEach(System.out::println); System.out.println("--------"); employees.stream() .sorted((x,y)->{ if (x.getAge()==y.getAge()){ return -x.getName().compareTo(y.getName()); }else { return Integer.compare(x.getAge(),y.getAge()); } }) .forEach(System.out::println); } }stream查找与匹配
package com.java8.demo.stream; import com.java8.pojo.Employee; import org.junit.Test; import java.util.Arrays; import java.util.List; import java.util.Optional; public class TestStreamAPI5 { /** * 查找与匹配 * allMatch——检查是否匹配所有元素 * anyMatch——检查是否至少匹配一个元素 * noneMatch——检查是否没有匹配的元素 * fin 4000 dFirst——返回第一个元素 * findAny——返回当前流中的任意元素 * count——返回流中元素的总个数 * max——返回流中最大值 * min——返回流中最小值 */ List<Employee> employees = Arrays.asList( new Employee("张三",18,9090.90, Employee.Status.FREE), new Employee("张三",34,9090.90, Employee.Status.FREE), new Employee("张三",18,9090.90, Employee.Status.VOCATION), new Employee("王武",35,4567.90, Employee.Status.FREE), new Employee("王二",45,9090.90, Employee.Status.FREE), new Employee("李四",34,567.90, Employee.Status.FREE), new Employee("小平",18,9090.90,Employee.Status.VOCATION) ); @Test public void test1(){ boolean b = employees.stream() .allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY)); System.out.println(b); boolean b1= employees.stream() .anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY)); System.out.println(b1); boolean b2= employees.stream() .noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY)); System.out.println(b2); Optional<Employee> op = employees.stream() .sorted((x, y) -> Double.compare(x.getSalary(), y.getSalary())) .findFirst(); System.out.println(op.get()); Optional<Employee> any = employees.parallelStream() .filter((e) -> e.getStatus().equals(Employee.Status.FREE)) .findAny(); System.out.println(any.get()); } @Test public void test2(){ long count = employees.stream() .count(); System.out.println(count); Optional<Employee> max = employees.stream() .max((x, y) -> x.getName().compareTo(y.getName())); System.out.println(max.get()); Optional<Integer> min = employees.stream() .map(Employee::getAge) // 通过map把工资先提取出来,再从工资中提取出来最小的 .min(Double::compare); 20000 System.out.println(min.get()); } }stream归约与收集
package com.java8.demo.stream; import com.java8.pojo.Employee; import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class TestStreamAPI6 { /** * 归约 * reduce(T identity, BinaryOperator) / reduce(BinaryOperator) --可以将流中元素反复结合起来,得到一个值 * 收集 * collect---将流转换为其他形式。接收一个Collector接口的实现,用于给Stream中元素做汇总的方法 */ List<Employee> employees = Arrays.asList( new Employee("张三",18,9090.90, Employee.Status.FREE), new Employee("张三",34,9090.90, Employee.Status.FREE), new Employee("张三",18,9090.90, Employee.Status.VOCATION), new Employee("王武",35,4567.90, Employee.Status.FREE), new Employee("王二",45,9090.90, Employee.Status.FREE), new Employee("李四",34,567.90, Employee.Status.FREE), new Employee("小平",18,9090.90,Employee.Status.VOCATION) ); @Test public void test1(){ List<Integer> list = Arrays.asList(1,1,1,1); Integer i = list.stream() .reduce(0, (x, y) -> x * y); // 参数identity作为起始值x, System.out.println(i); System.out.println("-------- "); Optional<Integer> sum = employees.stream() .map(Employee::getAge) .reduce(Integer::sum); System.out.println(sum.get()); } @Test public void test2(){ List<Integer> list = employees.stream() .map(Employee::getAge) .collect(Collectors.toList()); System.out.println(list); list.forEach(System.out::println); HashSet<Integer> collect = employees.stream() .map(Employee::getAge) .collect(Collectors.toCollection(HashSet::new)); System.out.println(collect); // 总数 Long collect1 = employees.stream() .collect(Collectors.counting()); System.out.println(collect1); Double collect2 = employees.stream() .collect(Collectors.averagingDouble(Employee::getSalary)); System.out.println(collect2); IntSummaryStatistics collect3 = employees.stream() .collect(Collectors.summarizingInt(Employee::getAge)); System.out.println(collect3); System.out.println(collect3.getAverage()); Integer collect4 = employees.stream() .collect(Collectors.summingInt(Employee::getAge)); System.out.println(collect4); // 分组 Map<Employee.Status, List<Employee>> collect5 = employees.stream() .collect(Collectors.groupingBy(Employee::getStatus)); System.out.println(collect5); // 多级分组 Map<Employee.Status, Map<String, List<Employee>>> collect6 = employees.stream() .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((employee) -> { if (employee.getAge() <= 35) { return "青年"; } else if (employee.getAge() <= 50) { return "中年"; } else { return "老年"; } }))); System.out.println(collect6); } // 分区 @Test public void test3(){ Map<Boolean, List<Employee>> collect = employees.stream() .collect(Collectors.partitioningBy((e) -> e.getAge() > 30)); System.out.println(collect); } @Test public void test4(){ String collect = employees.stream() .map(Employee::getName) .collect(Collectors.joining()); System.out.println(collect); String collect1 = employees.stream() .map(Employee::getName) .collect(Collectors.joining(",")); System.out.println(collect1); String collect2 = employees.stream() .map(Employee::getName) .collect(Collectors.joining(",","===","==")); System.out.println(collect2); } }stream练习
package com.java8.demo.stream; import com.java8.pojo.Trader; import com.java8.pojo.Transaction; import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.stream.Stream; public class TestTransaction { List<Transaction> transactions = null; @Before public void before(){ Trader raoul = new Trader("Raoul","Cambridge"); Trader mario = new Trader("Mario","Milan"); Trader alan = new Trader("Alan","Cambridge"); Trader brain = new Trader("Brain","Cambridge"); transactions = Arrays.asList( new Transaction(brain, 2011, 300), new Transaction(raoul, 2012, 1000), new Transaction(raoul, 2011, 400), new Transaction(mario, 2012, 710), new Transaction(mario, 2012, 700), new Transaction(alan, 2012, 950) ); } // 1. 找出2011年发生的所有交易,并按交易额排序(从低到高) @Test public void test1(){ transactions.stream() .filter((t) -> t.getYear()==2011) .sorted((e1,e2)-> Integer.compare(e1.getValue(),e2.getValue())) .forEach(System.out::println); } // 2。交易员都在哪些不同的城市工作过 @Test public void test2(){ transactions.stream() .map(Transaction::getTrader) .map(Trader::getCity) .distinct() .forEach(System.out::println); transactions.stream() .map((t)->t.getTrader().getCity()) .distinct() .forEach(System.out::println); } // 3。查找所有来自剑桥的交易员,并按姓名排序 @Test public void test3(){ transactions.stream() .map(Transaction::getTrader) .filter((s) -> s.getCity().equals("Cambridge")) .sorted((x,y)->x.getName().compareTo(y.getName())) .distinct() .forEach(System.out::println); } // 4。返回所有交易员的姓名字符串,按字母顺序排序 @Test public void test4(){ transactions.stream() .map(Transaction::getTrader) .map(Trader::getName) .sorted((x,y)->x.compareTo(y)) .forEach(System.out::println); System.out.println("-----------------"); String str = transactions.stream() .map((t) -> t.getTrader().getName()) .sorted() .reduce("", String::concat); System.out.println(str); System.out.println("-----------------"); transactions.stream() .map((t)->t.getTrader().getName()) .flatMap(TestTransaction::filterCharacter) .sorted() .forEach(System.out::println); } public static Stream<Character> filterCharacter(String str){ List<Character> list = new ArrayList<>(); for (char c : str.toCharArray()) { list.add(c); } return list.stream(); } // 5。有没有交易员是在米兰工作的? @Test public void test5(){ boolean b = transactions.stream() .map(Transaction::getTrader) .anyMatch((e) -> e.getCity().equals("Milan")); System.out.println(b); } // 6。打印生活在剑桥的交易员的所有交易额 @Test public void test6(){ Optional<Integer> cambridge = transactions.stream() .filter((e) -> e.getTrader().getCity().equals("Cambridge")) .map(Transaction::getValue) .reduce(Integer::sum); System.out.println(cambridge.get()); } // 7.所有交易中,最高的交易是多少 @Test public void test7(){ Optional<Integer> max = transactions.stream() .map(Transaction::getValue) .max(Integer::compareTo); System.out.println(max.get()); } // 8。 找到交易额最小的交易 @Test public void test8(){ Optional<Transaction> min = transactions.stream() .min((x, y) -> Integer.compare(x.getValue(), y.getValue())); System.out.println(min.get()); } }
并行流和串行流
optional容器类
接口中的默认方法与静态方法
接口中的默认方法:
接口默认方法的“类优先”原则
若一个接口中定义了一个默认方法,而另外一个父类或接口中又定义了一个同名的方法时
- 选择父类中的方法。如果一个父类提供了具体的实现,那么接口中具有相同名称和参数的默认方法会被忽略。
- 接口冲突。如果一个父接口提供方一个默认方法,而另一个接口也提供了一个具有相同名称和参数列表的方法(不管方法是否是默认方法),那么必须覆盖该方法来解决冲突。
日期时间API
package com.java8.date; import org.junit.Test; import java.time.*; import java.util.Date; public class TestLocalDateTime { // LocalDate、LocalTime、LocalDateTime @Test public void test1(){ Date date = new Date(); System.out.println(date); LocalDateTime ldt = LocalDateTime.now(); System.out.println(ldt); LocalDateTime localDateTime = LocalDateTime.of(2015, 03, 10, 13, 04, 34); System.out.println(localDateTime); System.out.println(localDateTime.plusDays(2)); System.out.println(localDateTime.getYear()); } // Instant:时间戳(以Unix元年:1970年1月1日 00:00:00到某个之间的毫秒值) @Test public void test2(){ Instant ins = Instant.now(); System.out.println(ins); OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8)); System.out.println(odt); System.out.println(ins.toEpochMilli()); Instant instant = Instant.ofEpochSecond(1); System.out.println(instant); } // Duration:计算两个"时间"之间的间隔 // Period:计算两个"日期"之间的间隔 @Test public void test3(){ Instant ins = Instant.now(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } Instant ins2 = Instant.now(); Duration duration = Duration.between(ins, ins2); System.out.println(duration); System.out.println(duration.getSeconds()); System.out.println(duration.toMillis()); System.out.println("--------"); LocalTime lt = LocalTime.now(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } LocalTime lt2 = LocalTime.now(); Duration duration2 = Duration.between(lt, lt2); System.out.println(duration2); } }时间校正器
// 时间校正器 @Test public void test4(){ LocalDateTime ldt = LocalDateTime.now(); System.out.println(ldt); LocalDateTime ldt1 = ldt.withDayOfMonth(10); System.out.println(ldt1); LocalDateTime ldt2 = ldt.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)); System.out.println(ldt2); // 自定义:下一个工作日 LocalDateTime ldt5 = ldt.with((l) -> { LocalDateTime ldt4 = (LocalDateTime) l; DayOfWeek dow = ldt4.getDayOfWeek(); if (dow.equals(DayOfWeek.FRIDAY)) { return ldt4.plusDays(3); } else if (dow.equals(DayOfWeek.SATURDAY)) { return ldt4.plusDays(2); } else { return ldt4.plusDays(1); } }); System.out.println(ldt5); }DateTimeFormatter: 格式化时间/日期
// DateTimeFormatter: 格式化时间/日期 @Test public void test5(){ DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME; DateTimeFormatter dtf1 = DateTimeFormatter.ISO_DATE; LocalDateTime ldt = LocalDateTime.now(); String format = ldt.format(dtf); System.out.println(format); String format1 = ldt.format(dtf1); System.out.println(format1); System.out.println("-----------"); DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日"); String strDate = dtf2.format(ldt); System.out.println(strDate); System.out.println("-------"); // LocalDateTime newDate = ldt.parse(strDate, dtf2); // System.out.println(newDate); }
重复注解与类型注解
package com.java8.annotation; import com.java8.service.MyAnnotation; import org.junit.Test; import java.lang.reflect.Method; /** * 重复注解与类型注解 */ public class TestAnnotation { @Test public void test1() throws NoSuchMethodException { Class<TestAnnotation> clazz = TestAnnotation.class; Method m1 = clazz.getMethod("show"); MyAnnotation[] mas = m1.getAnnotationsByType(MyAnnotation.class); for (MyAnnotation ma : mas) { System.out.println(ma.value()); } } @MyAnnotation("Hello") @MyAnnotation("world") public void show(){ } }
package com.java8.service; import org.springframework.stereotype.Component; import java.lang.annotation.*; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; @Repeatable(MyAnnotations.class) @Target({TYPE,METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface MyAnnotation { String value() default "java8"; }
package com.java8.service; import org.springframework.stereotype.Component; import java.lang.annotation.*; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; @Target({TYPE,METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface MyAnnotations { MyAnnotation[] value(); }
相关文章推荐
- java8新特性学习笔记(一) Lambda表达式
- Java8学习笔记 — 【Lambda表达式】
- 一、JAVA8学习笔记 Lambda表达式快速入门
- Java学习笔记-Lambda表达式及內建函数式接口
- JAVA8的新特性学习笔记-(lambda、stream)
- java lambda表达式学习笔记
- JAVA 1.8 新特性学习(2) lambda表达式
- Java Lambda 表达式学习笔记
- [学习笔记] Java核心技术 卷一:基础知识 接口、lambda表达式与内部类(三)
- Java学习笔记(十)Lambda表达式
- C#特性 学习笔记(Lambda表达式 迭代)
- Java 进阶,学习笔记-12 函数式编程以及 Lambda 表达式
- Java8 学习笔记--函数式接口与lambda表达式的关系
- Java8学习笔记----Lambda表达式 (转)
- java lambda表达式 闭包学习笔记
- Java8学习笔记(二)—— Lambda表达式
- java8学习笔记之lambda表达式
- Java 8特性学习 --- Lambda表达式
- Java学习笔记(Lambda表达式、File类、IO流)
- Java8学习笔记(一)-初步认识Lambda表达式