Java Lambda表达式和Stream使用方式
Lambda表达式和Stream流的使用使得代码量优化,同时处理有些操作变得相对来说较容易,以下是简单的一些使用。
这里为了演示定义了一个Author类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Author implements Comparable<Author>{
private Long id;
private String name;
private Integer age;
private String intro;
private List<Book> books;
}
这里定义了Book类
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode//用于后期的去重使用
public class Book {
private Long id;
private String name;
//分类
private String category;//格式:"哲学,小说"
//评分
private Integer score;
//简介
private String intro;
}
Stream流常用的操作方法以及Lambda表达式
举个例子:这里为了输出每个人的姓名,一般我们使用foreach
List<Author> authors = getAuthors();
for (Author author: authors) {
System.out.println(author.getName());
}
使用Sream流操作:
现将List以流的形式处理,再调用其方法。这里介绍几个常用的方法
map():对集合中每个元素都进行的操作
filter():根据条件判断过滤掉元素
distinct():去重
foreach():遍历
collect():返回集合
在调用这些方法时,参数传入的是一个匿名接口,重写接口中的方法来完成我们需要的操作,每个方法里可调用的接口以及实现的方法很多,根据需要可以自行查看选用,这里的Function接口内重写的方法就是将Author类传入,以String 类型(类型是自选的)值返回,这里的Consumer接口类实现的accept方法可以打印,内部还有其他方法可以自行了解使用,同时foreach也是终结操作因此到这Stream流的一个简单使用就完成了。
authors.stream().map(new Function<Author, String>() {
@Override
public String apply(Author author) {
return author.getName();
}
}).forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
肯定也许会认为Stream流这个过程有点复杂,但其实如果要完成操作比较复杂的处理是很有用的。
上面的代码看起来多少有点比原来的要理解复杂点,但是使用IDEA,在函数入口使用Alt+Enter可以转化为Lambda表达式表示:
authors.stream().map(author -> author.getName()).forEach(s -> System.out.println(s));
Lambda表达式的使用前提是只重写了一个方法,并且传递有参数,那么可以直接写要传入的参数 + 右箭头+返回语句。因此Lambda主要关注于输入的参数以及返回的类型,这个过程中你使用的接口以及重写的方法都是我们需要认识的内容,所以要熟练使用Lambda表达式实现流操作,我们先要学会使用流操作当中的方法,然后再替换为Lambda表达式,自然而然就很容易看明白并写出来。
数组类型转化为stream形式
Integer[] arr = {1,2,3,4,5};
Stream<Integer> stream = Arrays.stream(arr);//方式 1
Stream<Integer> stream = Stream.of(arr);//方式 2
filter() distinct()示例(数组去重并满足条件输出):
//匿名类方式
stream.distinct()
.filter(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
return integer > 2;
}
})
.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer);
}
});
//替换为lambda
stream.distinct()
.filter(integer -> integer>2)
.forEach(integer -> System.out.println(integer));
Map<key,value>转化为stream形式
Map<String,Integer> map = new HashMap<>();
map.put(...);
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
Stream<Map.Entry<String, Integer>> stream = entrySet.stream();
判断value大于16的元素
stream.filter(new Predicate<Map.Entry<String, Integer>>() {
@Override
public boolean test(Map.Entry<String, Integer> entry) {
return entry.getValue()>16;
}
}).forEach(new Consumer<Map.Entry<String, Integer>>() {
@Override
public void accept(Map.Entry<String, Integer> entry) {
System.out.println(entry.getKey()+"==="+entry.getValue());
}
});
//lambda
stream.filter(entry -> entry.getValue()>16)
.forEach(entry -> System.out.println(entry.getKey()+"==="+entry.getValue()));
sort()排序
List<Author> authors = getAuthors();
// 对流中的元素按照年龄进行降序排序
authors.stream()
.sorted(new Comparator<Author>() {
@Override
public int compare(Author o1, Author o2) {
return o2.getAge() - o1.getAge();
}
}) // lambda: .sorted((o1, o2) -> o2.getAge() - o1.getAge())
.forEach(author -> System.out.println(author.getAge()));
flatMap():处理后返回stream类型
// 打印所有书籍的名字。要求对重复的元素进行去重。
// 因为Author中属性有List<Book>,这里从Author中取出该属性并返回stream类型继续操作
List<Author> authors = getAuthors();
authors.stream()
.flatMap(new Function<Author, Stream<? extends Book>>() {
@Override
public Stream<? extends Book> apply(Author author) {
return author.getBooks().stream();
}
}) // lambda :flatMap(author -> author.getBooks().stream())
.distinct()
.forEach(book -> System.out.println(book.getName()));
collect() 返回集合:
//例 1 获取一个存放所有作者名字的List集合。
List<Author> authors = getAuthors();
List<String> nameList = authors.stream()
.map(author -> author.getName())
.collect(Collectors.toList());
//例 2 获取一个所有书名的Set集合。
List<Author> authors = getAuthors();
Set<Book> books = authors.stream()
.flatMap(author -> author.getBooks().stream())
.collect(Collectors.toSet());
//例 3 获取一个Map集合,map的key为作者名,value为List<Book>
List<Author> authors = getAuthors();
Map<String, List<Book>> map = authors.stream()
.distinct()
.collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
除此之外还有很多方法:
reduce() :返回最终一项处理结果,
allMatch():都满足匹配条件 返回true
noneMatch() :都不满足匹配条件 返回true
mapToInt() :当对对象某一整形数据做多次操作时,那么使用此方法就保证不用多次从对象中拆解此属性出来操作,而是一次就把所有的整数数据继续到后面所有操作当中(也就是直接变成了IntSteam)
stream.parallel():该方法是启用并行流,开启多线程处理当前流中的数据,对于大量多次的数据操作可以考虑使用