lambda表达式是JDK8新特性的一种;可以对某些匿名内部类进行简写;
核心原则:可推导可省略
基本格式:(参数列表)-> {代码}
lambda表达式例一:
new Thread(new Runnable() {
public void run() {
System.out.println("简单线程调用");
}
}).start();
改写成lambda表达是形式为:
new Thread(()-> {
System.out.println("lambda表达式第一次应用");
}).start();
原则就是一个匿名内部类实现的是一个接口,且里面只有一个方法是抽象方法
lambda表达式例二:
public static void main(String[] args) {
int i = calculateNum(new IntBinaryOperator() {
@Override
public int applyAsInt(int left, int right) {
return left + right;
}
});
//System.out.println(i);
}
public static int calculateNum(IntBinaryOperator operator){
int a = 10;
int b = 120;
return operator.applyAsInt(a,b);
}
转换成lambda表达式的形式为:
public static void main(String[] args) {
int i = calculateNum((left, right) ->{
return left + right;
});
System.out.println(i);
}
public static int calculateNum(IntBinaryOperator operator){
int a = 101;
int b = 120;
return operator.applyAsInt(a,b);
}
lambda表达式例三:
public static void main(String[] args) {
PrintNum(new IntPredicate() {
@Override
public boolean test(int value) {
return value % 2==0;
}
});
}
public static void PrintNum(IntPredicate predicate){
int arr[] = {1,2,3,4,5,6,7,8,9,10};
for (int i : arr) {
if(predicate.test(i)){
System.out.println(i);
}
}
转换成lambda表达式代码为:
public class LambdaTest {
public static void main(String[] args) {
PrintNum((value) ->{
return value % 2!=0;
});
}
lambda表达式例四:
Integer integer = typeConver(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.valueOf(s);
}
});
System.out.println(integer);
}
public static <R> R typeConver(Function<String,R> function){
String str = "12345";
R result = function.apply(str);
return result;
}
转换成lambda表达式形式为:
Integer integer = typeConver((String s)-> Integer.valueOf(s)
);
System.out.println(integer);
}
lambda表达式例五:
public static void main(String[] args) {
forEachArr((value) -> System.out.println(value));
}
public static void forEachArr(IntConsumer consumer){
int[] arr = {1,2,3,4,5,6,7,8,9,10};
for (int i :arr) {
consumer.accept(i);
}
}
上述lambda表达式可以省略,省略规则可不记;
Stream流概念:
对集合和数组进行操作:
Stream例一:打印list集合中所有年龄小于18岁的作家的名字,并去重;
List<Author> authors = getAuthors();
authors.stream() //把list集合转换成流;
.distinct() //对几个去重
.filter(author -> author.getAge()<18) //筛选出年龄小于18岁的作者集合
.forEach(author -> System.out.println(author.getName())); //这边foreach是终结操作,打印出作者姓名
}
常见操作:
(1)创建流:
①单例集合: 集合对象.stream()
②数组集合:Arrays.stram(数组名)或者stream.of(数组名)进行创建
③双列集合:转换成单例对象再创建 如 map.entrySet().stream()
(2)中间操作:
①filter:对流中进行过滤操作
例如:打印所有姓名长度大于1的作家的姓名
public static void main(String[] args) {
List<Author> authors = getAuthors();
authors.stream() //把list集合转换成流;
.filter(author -> author.getName().length()>1)
.forEach(author -> System.out.println(author.getName()));
}
②map:将流中的对象进行转化或者计算,这边是转换成字符串进行操作
例如:输出所有作家的姓名
public static void main(String[] args) {
List<Author> authors = getAuthors();
authors.stream() //把list集合转换成流;
.map(author -> author.getName())
.forEach(string-> System.out.println(string));
}
③distinct:可以去除流中的重复元素:实体类中必须重写equal()方法
④sorted:对流中的元素进行排序,这边实体类需要实现Comparable<>接口
例如:对流中的元素按照年龄进行降序排列,并且要求不能有重复元素;
第一种情况,sorted()不带参数,需实现Comparable方法
public class Author implements Comparable<Author>
@Override
public int compareTo(Author o) {
return o.getAge()-this.getAge(); //这边表示按年龄进行降序排序
}
List<Author> authors = getAuthors();
authors.stream() //把list集合转换成流;
.distinct()
.sorted()
.forEach(author -> System.out.println(author));
}
第二次方式:sorted()方法带参数,将年龄进行升序排列
List<Author> authors = getAuthors();
authors.stream() //把list集合转换成流;
.distinct()
.sorted((o1, o2) -> o1.getAge()-o2.getAge())
.forEach(author -> System.out.println(author));
}
⑤limit:设置流的最大长度
例如:对流中元素按照年龄进行降序排列,并且要求不能有重复元素,然后打印其中年龄最大的两个作家的姓名;
List<Author> authors = getAuthors();
authors.stream() //把list集合转换成流;
.distinct() //将流中的元素进行去重
.sorted((o1, o2) -> o2.getAge()-o1.getAge())
.limit(2)
.forEach(author -> System.out.println(author.getName()));
⑥skip:跳过流中某些元素
例如:对流中元素按照年龄进行降序排列,并且要求不能有重复元素,然后打印除了年龄最大的作家的姓名;
List<Author> authors = getAuthors();
authors.stream() //把list集合转换成流;
.distinct() //将流中的元素进行去重
.sorted((o1, o2) -> o2.getAge()-o1.getAge())
.skip(1)
.forEach(author -> System.out.println(author.getName()));
⑦flatMap:可以把流中的一个对象转换成多个对象作为流的元素
例一:打印所有书籍的名字(书籍和作家的名字是多对一,书籍在作家表中是list集合),要求对重复元素进行去重;
List<Author> authors = getAuthors();
authors.stream() //把list集合转换成流;
.flatMap(author -> author.getBooks().stream()) //转换成book流对象
.distinct() //这边是对book集合进行去重;
.forEach(book -> System.out.println(book.getName()));
例二:对字符串进行分割
List<Author> authors = getAuthors();
authors.stream() //把list集合转换成流;
.flatMap(author -> author.getBooks().stream()) //转换成book流对象
.distinct() //这边是对book集合进行去重;
.flatMap(book -> Arrays.stream(book.getCategory().split(","))) //因为分类是数组,所以需要转换
.distinct()
.forEach(category-> System.out.println(category));
(3)终结操作:
①forEach(),对流中的元素进行遍历操作
②count:可以获取流中元素个数
例如:
打印作家所出书籍的数量,注意去重;
List<Author> authors = getAuthors();
long count = authors.stream() //把list集合转换成流;
.flatMap(author -> author.getBooks().stream())
.distinct()
.count();
System.out.println(count);
③min&max 取出流中的最大值 最小值
分别获取这些作家的所出书籍的最高分和最低分并打印
List<Author> authors = getAuthors();
Optional<Integer> max = authors.stream() //把list集合转换成流;
.flatMap(author -> author.getBooks().stream())
.map(book -> book.getScore())
.max((score1, score2) -> score1 - score2);
Optional<Integer> min = authors.stream() //把list集合转换成流;
.flatMap(author -> author.getBooks().stream())
.map(book -> book.getScore())
.max((score1, score2) -> score2 - score1);
System.out.println(max.get());
System.out.println(min.get());
④collect:把当前流转换成一个集合
例一:获取一个存放所有作者名字的list集合
List<String> collect = authors.stream()
.distinct()
.map(author -> author.getName())
.collect(Collectors.toList());
System.out.println(collect);
例二:获取一个所有书名的set集合
//获取一个所有书名的set集合
.distinct()
.map(author -> author.getName())
.collect(Collectors.toSet());
System.out.println(collect);
例三:获取一个map,map的可以为作者名,value为List<Book>,map集合必须指定key和value
List<Author> authors = getAuthors();
Map<String, List<Book>> map = authors.stream()
.distinct()
.collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
System.out.println(map);
⑤anyMatch:可以用来判断是否有任意符合匹配条件的元素,结果为boolean类型
例:判断是否有年龄在29岁的作家
List<Author> authors = getAuthors();
boolean b = authors.stream()
.distinct()
.anyMatch(author -> author.getAge() > 29);
System.out.println(b);
⑥allMatch/noneMatch:可以用来判断是否全部符合/不符合匹配条件的元素
⑦findAny:获取流中的任意一个元素
例:获取一个年龄大于18的作家,如果存在则输出它的姓名
List<Author> authors = getAuthors();
Optional<Author> optional = authors.stream()
.distinct()
.filter(author -> author.getAge() > 18)
.findAny();
optional.ifPresent(author-> System.out.println(author.getName()));
⑧findFrist:获取流中的第一个元素
例:获取年龄最小的作家,并输出他的姓名
List<Author> authors = getAuthors();
Optional<Author> optional = authors.stream()
.distinct()
.sorted((o1, o2) -> o1.getAge()-o2.getAge())
.findFirst();
optional.ifPresent(author-> System.out.println(author.getName()));
⑨reduce:归并,对流中的数据按照你制定的计算方式计算出一个结果(缩减操作)
例一:使用reduce求所有作者年龄的和
List<Author> authors = getAuthors();
Integer reduce = authors.stream()
.map(author -> author.getAge())
.reduce(0, (result, element) -> result + element); //这边一个参数0表示初始值
//result+element表示结果加上遍历的值
System.out.println(reduce);
例二:使用reduce求所有作者中年龄最大的值
List<Author> authors = getAuthors();
Integer reduce = authors.stream()
.map(author -> author.getAge())
.reduce(0, (result, element) -> result > element ? result:element);
System.out.println(reduce);
例三:使用reduce求所有作者中年龄最小的值;
List<Author> authors = getAuthors();
Integer min = authors.stream()
.map(author -> author.getAge())
.reduce(Integer.MAX_VALUE, (result, element) -> result < element ? result:element);
System.out.println(min);
Stream流的注意事项:
①惰性求值:必须要有终结操作,不然中间操作不会被执行;
②流是一次性的;
③不会影响原始数据:
Optional概述
:主要是防止空指针异常;
3.1创建Optional对象
一般都是使用Optional的静态方法ofNullable()
List<Author> authors = getAuthors();
Stream<Author> stream = authors.stream();
Optional<List<Author>> optionalAuthors = Optional.ofNullable(authors);
optionalAuthors.ifPresent(authors1 ->stream.forEach(author -> System.out.println(author.getName())));
使用方法二:
Optional<Author> authorOptional = getAuthorOptional();
authorOptional.ifPresent(author->system.out.println(author.getName()));
3.2 安全消费值: 使用ifPresent方法;
3.3安全获取值:不推荐使用get方法,里面有orElseGet方法可以设置默认值,orElseThrow可以抛出一个异常
List<Author> authors = getAuthors();
Optional<List<Author>> optionalAuthors = Optional.ofNullable(authors);
List<Author> authors1 = optionalAuthors.get();
System.out.println(authors1);
3.4过滤数据:使用filter进行过滤;
3.5判断:IfPresent:返回boolean值;
3.6 数据转换:map方法
函数式接口的概述:接口中只有一个抽象方法;
@FunctionalInterface注解标识的都是函数式接口
4.1默认方法:包括and,or,negate(取反)等
5.方法引用:集合必须带上泛型 我觉得
alt+enter