您的位置:首页 > 编程语言 > Java开发

Java8新特性-Lambda表达式-Stream API等(学习笔记)

2020-06-05 19:20 36 查看

Java8新特性-Lambda表达式-Stream API等_尚硅谷__李贺飞
内容:

  1. lambda表达式(重点)
  2. 函数式表达式
  3. 方法引用与构造器引用
  4. Stream API(重点)
  5. 接口中的默认方法与静态方法
  6. 新实践日期API
  7. 其他新特性

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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: