Day1:
1. Lambda表达式
- Lambda表达式的基本结构:
(param1,param2,param3,paramN) ->{body}
- 关于函数式接口:
- 如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口。
- 如果我们在某个接口上声明了FunctionalInterface注解,那么编译器就会按照函数式接口的定义来要求该接口。
- 如果某个接口只有一个抽象方法,但我们没有给该接口声明FunctionalInterface注解,那么编译器依旧会将该接口看作是函数式接口。
ps(为什么函数式接口中只有一个抽象方法:因为在Lambad表达式中并没有指定方法名字(所以函数式接口中的方法只能有一个))
在java中Lambad表示式是对象,他们必须依附于一类特别的对象函数——函数式接口(functional interface)
test2.myTest(()-> {
System.out.println("MyInterface");
});
//method reference(方法引用)
list.forEach(System.out::println);
List<String> list = Arrays.asList("nihao", "xiaoming");
list.forEach(item -> System.out.println(item.toUpperCase()));
List<String> list1 = new ArrayList<>();
list.forEach(item -> list1.add(item.toUpperCase()));
list.stream().map(item ->item.toUpperCase()).forEach(item -> System.out.println(item));
list.stream().map(String::toUpperCase).forEach(item-> System.out.println(item));
运行结果
"C:\Program Files\Java\jdk1.8.0_201\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.1\lib\idea_rt.jar=59655:C:\Program Files\JetBrains\IntelliJ IDEA 2019.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_201\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\rt.jar;C:\Users\user\ideaTest\java8\target\classes" com.mobius.vision.jdk8.Test3
NIHAO
XIAOMING
NIHAO
XIAOMING
NIHAO
XIAOMING
Lamdba表达式的作用:
- 传递行为,而不仅仅是值。
- 提升抽象层次
- API重用性更好
- 更加灵活
Java Lambda结构
- 一个Lambda表达式可以有零个或多个参数
- 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同。
- 空圆括号代表参数集为空。例如:()->42
- (args1,args2....)->{body} Lambda表达式的语法
System.out.println(functionTest.addThe(1,2,(value1,value2)->value1+value2,value3->value3*value3));
//先将1和2作为参数给biFunction:1+2得3然后将3作为参数给function3*3得9
}
public Integer addThe(int a,int b,BiFunction<Integer,Integer,Integer> biFunction,
Function<Integer,Integer> function){
return biFunction.andThen(function).apply(a,b);
}
Lambda表达式的一些操作
package com.mobius.vision.jdk8;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
/**
* @author NingXioaoming
* @createTime 2019/11/8 11:05
* @description
*/
public class Test4 {
public static void main(String[] args) {
Person person = new Person();
person.setUserName("zhangsan");
person.setAge(18);
Person person1 = new Person();
person1.setUserName("lisi");
person1.setAge(20);
Person person2 = new Person();
person2.setUserName("wangwu");
person2.setAge(22);
List<Person> list = Arrays.asList(person, person1, person2);
Test4 test4 = new Test4();
List<Person> persons = test4.getPersonsByUsername("zhangsan", list);
persons.forEach(pp-> System.out.println(pp.getUserName()));
List<Person> personsByUsername = test4.getPersonsByUsername(20, list);
personsByUsername.forEach(user-> System.out.println(user.getAge()));
List<Person> personsByT = test4.getPersonsByT(19, list, (age, list1) ->
list1.stream().filter(person3 -> person3.getAge() > age).collect(Collectors.toList())
);
personsByT.forEach(person3 -> System.out.println(person3.getAge()));
}
public List<Person> getPersonsByT(Integer age,List<Person> list,BiFunction<Integer,List<Person>,List<Person>> biFunction){
return biFunction.apply(age,list);
}
public List<Person> getPersonsByUsername(String userName, List<Person> list){
list.forEach(person -> System.out.println(person.getUserName()));
return list.stream().filter(person1 -> person1.getUserName().equals(userName)).collect(Collectors.toList());
}
public List<Person> getPersonsByUsername(Integer age,List<Person> list){
BiFunction<Integer,List<Person>,List<Person>> biFunction =(age1,personList)->
personList.stream().filter(person -> person.getAge()>age).collect(Collectors.toList());
return biFunction.apply(age,list);
}
}
Day2:
1. Optional
optional的一些使用方法
Optional<String> heloo = Optional.of("1111");//一定不为空
Optional<String> heloo1 = Optional.empty();//一定为空
Optional<String> heloo2 = Optional.ofNullable("1111");//不确定是否为空
heloo.ifPresent(item -> System.out.println(item));
判断person是否为空方法
List<String> list = Arrays.asList("nihapo", "wohap");
List<String> list1 = Arrays.asList();
Person person = new Person();
person.setList(list1);
Optional<Person> optional = Optional.ofNullable(person);
//判断person是否为空方法
System.out.println(optional.map(thePerson->thePerson.getList()).orElse(Collections.emptyList()));
方法引用
- 方法引用:method reference
- 方法引用实际上是个Lambda表达式的一种语法糖
- 我们可以将方法引用看做是一个【函数指针】,function pointer,
- 方法引用共分为4类
- 类名::静态方法名。
- 引用名(对象名)::实类方法名。
- 类名::示例方法名。
- 构造方法引用:类名::new
Student student1 = new Student("zhangsan", 18);
Student student2 = new Student("lisi", 20);
Student student3 = new Student("wangwo", 22);
Student student4 = new Student("xuebing", 16);
List<Student> list = Arrays.asList(student1, student2, student3, student4);
list.sort((studentParam1,studentParam2)->Student.compareStudentByScore(studentParam1,studentParam2));
//上下这两个排序等价,下面是上面的方法糖
//1. 类名::静态方法名
list.sort(Student::compareStudentByScore);
list.forEach(student -> System.out.println(student.getScore()));
//2.引用名(对象名)::实类方法名。
StudentCompare studentCompare = new StudentCompare();
list.sort(studentCompare::compareByScore);
list.forEach(student -> System.out.println(student.getScore()));
//3.类名::示例方法名。
list.sort(Student::compareByScore);
//4.构造方法引用:类名::new
Stream(流)
- 流由3部分构成:
- 源
- 零个或多个中间操作:中间操作都会返回一个Stream对象,例如:Stream<Student>,Stream<Integer>。
- 终止操作:终止操作则不会返回Stream类型,可能不返回值,也可能返回其他类型的单个值。
- 流操作的分类:
- 惰性求值
- 及早求值
List<Integer> list = Arrays.asList(2, 4, 5, 6, 8);
list.stream().map(i->i*2).forEach(integer -> System.out.println(integer));
//给list中的每一个元素*2然后再相加操作
//这是一个流:list是源,map是中间操作,reduce是终止操作
System.out.println(list.stream().map(i -> i*2).reduce(0,Integer::sum));
Stream(流)的一些操作
//一个流只能被操作一次 多次操作编译报错:Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
Stream<String> stream = Stream.of("hello","nihap");
// String[] strings = stream.toArray(length -> new String[length]);
//等价于上面 这里使用方法引用
// String[] strings1 = stream.toArray(String[]::new);
//将stream转化成list集合
List<String> collect = stream.collect(Collectors.toList());
collect.forEach(System.out::println);
Stream<String> stream1 = Stream.of("hello","nihap","word");
// List<String> collect1 = stream1.collect(Collectors.toList());
ArrayList<String> collect1 = stream1.collect(() -> new ArrayList(), (theList, iteam) -> theList.add(iteam), (theList1, theList2) -> theList1.addAll(theList2));
//下面的方法引用等价于上面的lambda表达式
stream1.collect(ArrayList::new,ArrayList::add,ArrayList::addAll);
collect1.forEach(item-> System.out.println(item));
//将流转化成LinkedHashSet以及其他....
LinkedHashSet<String> collect2 = stream2.collect(Collectors.toCollection(LinkedHashSet::new));
//将流对象转化成String
String collect3 = stream2.collect(Collectors.joining());
//将集合中的元素转化成大写并输出Map给一个元素对这个元素操作(加减乘除等...)之后返回一个新的元素
list.stream().map(String::toUpperCase).collect(Collectors.toList()).forEach(item-> System.out.println(item));
Stream<List<Integer>> listStream = Stream.of(Arrays.asList(1, 2), Arrays.asList(2, 3), Arrays.asList(4, 5));
//flatMap的用法:将多个集合组成的流压成一个流
listStream.flatMap(theList->theList.stream()).map(item->item*item).forEach(integer -> System.out.println(integer));
//通过Stream的generate静态方法生成Stream对象,然后输出Stream流中的第一个元素
Stream<String> stream1 = Stream.generate(UUID.randomUUID()::toString);
stream1.findFirst().ifPresent(System.out::println);
//构造88个偶数放到Stream流中然后输出2,4,8,16 n+1=n*n
Stream.iterate(2,item->item*2).limit(88).forEach(System.out::println);
Stream<Integer> stream3 = Stream.iterate(1, item -> item + 2).limit(6);
//取出stream3中的大于2的元素,每一个乘以二,然后再提出前两个元素,然后再取出前两元素,然后去掉重复元素,然后再相加
System.out.println(stream3.filter(itemIn -> itemIn > 2).mapToInt(item -> item * 2).skip(2).limit(2).distinct().sum());
//Stream.summaryStatistics();返回IntSummaryStatistics对象包含了一些数字的结果(max,min,count。。。。)
IntSummaryStatistics intSummaryStatistics = stream3.filter(itemIn -> itemIn > 2).mapToInt(item -> item * 2).skip(2).limit(2).distinct().summaryStatistics();
System.out.println(intSummaryStatistics.getMax());
System.out.println(intSummaryStatistics.getMin());
System.out.println(intSummaryStatistics.getSum());
System.out.println(intSummaryStatistics.getCount());
- 内部迭代:将n个条件拼接,然后进行循环查找。
flatMap的用法
List<String> list1 = Arrays.asList("hello ww", "hello ee", "qq hello");
//flatMap:将多个stream打平放到一个stream中 (单词去重)
list1.stream().map(item->item.split(" ")).flatMap(Arrays::stream).distinct().collect(Collectors.toList()).forEach(System.out::println);
分组和分区的操作
List<Student> students = Arrays.asList(student, student1, student2, student3);
//根据Student的name进行分组类似sql的group by
Map<String, List<Student>> map = students.stream().collect(Collectors.groupingBy(Student::getName));
Map<Integer, List<Student>> map1 = students.stream().collect(Collectors.groupingBy(Student::getScore));
Map<String, Long> collect = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.counting()));
Map<String, Double> collect1 = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.averagingInt(Student::getScore)));
//对数据分区
Map<Boolean, List<Student>> collect2 = students.stream().collect(Collectors.partitioningBy(student7 -> student7.getScore() > 80));
collect方法的详细介绍:
网友评论