-
基本格式:(参数列表)->{执行代码块}
-
组成Lambda表达式三要素:形式参数、箭头、代码块
-
使用Lambda表达式前提:1)有一个接口;2)接口中有且仅有一个抽象方法
Lambda简洁模式:
-
参数类型可以省略,多个参数情况下不能只省略一个参数类型
-
参数有且只有一个,可以省略小括号
-
如果代码块只有一条,可以省略大括号和分号,如果有return,return也要省略
Lambda表达式注意事项:
-
有接口,接口中有且仅有一个抽象方法
-
使用Lambda必须有上下文环境,才能推导出Lambda对应接口
Lambda和匿名内部类区别:
-
Lambda只能搞接口
-
Lambda不能处理接口中有两个方法的情况
-
实现原理不同,匿名内部类编译后会产生一个单独的.class字节码文件
-
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程已经启动");
}
}).start();
//使用lambda表达式书写
new Thread(() -> {
System.out.println("启动一个新的线程");
}).start();
}
创建Stream流
单列集合:集合对象.stream()
List<Author> author =new ArrayList<>();
author.stream()
数组:Arrays.stream( 数组) 或者使用 Stream.of()来创建
Integer [] arr={1,2,3,4,5}
Stream<Integer> stream = Arrarys.stream(arr);
Stream<Integer> stream1=Stream.of(arr)
双列集合:转换为单列集合后在进行创建
HashMap<String, Integer> map = new HashMap<>();
map.put("林聪",32);
map.put("图图",32);
map.put("郭大侠",23);
Stream<Map.Entry<String, Integer>> stream = map.entrySet().stream();
遍历map集合的4种方法:
HashMap<String, Integer> map = new HashMap<>();
map.put("林聪",32);
map.put("图图",32);
map.put("郭大侠",23);
//方法1:通过获取key的set集合遍历key
Set<String> keySet = map.keySet();
for (String s : keySet) {
System.out.println(s+map.get(s));
}
//方法2:通过拿到netrySet直接进行遍历
for (Map.Entry<String, Integer> entry : map.entrySet()) {
}
//方法3:通过拿到entrySet使用Iterator进行遍历
Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String, Integer> next = iterator.next();
}
//方法4:通过map获取所有的值进行遍历
Collection<Integer> values = map.values();
for (Integer value : values) {
}
Stream中间操作之filter
List<Author> authors = getAuthors();
//打印所有作家名称大于2个字符的名称
authors.stream().filter(author -> author.getName().length()>2).forEach(author -> System.out.println(author.getName()));
//原始方式:
List<Author> authors = getAuthors();
//打印所有作家名称大于2个字符的名称
authors.stream().filter(new Predicate<Author>() {
@Override
public boolean test(Author author) {
return author.getName().length() > 2;
}
}).forEach(new Consumer<Author>() {
@Override
public void accept(Author author) {
System.out.println(author.getName());
}
});
//使用熟练后可以直接装成lambda表达式
Stream中间操作之map
map操作可以将流中的进行计算或者转换
//只打印作者的姓名,lambda方式
authors.stream().map(Author::getName).forEach(System.out::println);
//匿名内部类方式:
authors.stream().map(new Function<Author, String>() {
@Override
public String apply(Author author) {
return author.getName();
}
}).forEach(System.out::println);
//对所有的年龄加10
authors.stream().map(Author::getAge).map(age->age+10).forEach(System.out::println);
Stream中间操作之distinct
distinct可以将重复的流数据进行去除
注意:distinct方法是依赖Object的equals方法来进行判断是否为相同对象的。所以需要注意重写equals方法。
Stream中间操作之scorted(排序)
如果使用空参的scorted需要对流中的对象重写Compare接口
//lambda方式
authors.stream().sorted((o1, o2) -> o1.getAge()-o2.getAge()).forEach(author -> System.out.println(author.getAge()));
//匿名内部类方式
authors.stream().sorted(new Comparator<Author>() {
@Override
public int compare(Author o1, Author o2) {
return o1.getAge()-o2.getAge();
}
}).forEach(author -> System.out.println(author.getAge()));
Stream中间操作符之limit(n)
设置流的最大长度超出的部分将会被抛弃。
//截取前10个
authors.stream().limit(10).forEach(System.out::println);
Stream中间操作符之skip(n)
跳过流中的前N个元素
//忽略流中第一个元素
authors.stream().skip(1).forEach(System.out::println);
Stream中间操作符之flatMap
map只能把一个对象转换成另一个对象来作为流中的元素,而flatMap可以将一个对象转换成多个对象作为流中的元素,获取对象中一个List<Book>的属性并转成流。
//匿名内部类实现
authors.stream().flatMap(new Function<Author, Stream<? extends Book>>() {
@Override
public Stream<? extends Book> apply(Author author) {
return author.getBooks().stream();
}
}).forEach(book -> System.out.println(book.getName()));
//lambda方式实现
authors.stream().flatMap(author -> author.getBooks().stream()).forEach(book -> System.out.println(book.getName()));
//打印现有数据的全部分类,要求对分类进行去重
//使用lambda方式实现
authors.stream().flatMap(author -> author.getBooks()
.stream()).flatMap(book -> Arrays.stream(book.getCategory().split("、"))).distinct()
.forEach(System.out::println);
//使用匿名内部类实现
authors.stream().flatMap(new Function<Author, Stream<? extends Book>>() {
@Override
public Stream<? extends Book> apply(Author author) {
return author.getBooks()
.stream();
}
}).flatMap(new Function<Book, Stream<? extends String>>() {
@Override
public Stream<? extends String> apply(Book book) {
return Arrays.stream(book.getCategory().split("、"));
}
}).distinct()
.forEach(System.out::println);
Stream终结操作符forEarch()
//打印作者名称
authors.forEach(author -> System.out.println(author.getName()));
//匿名类实现
authors.forEach(new Consumer<Author>() {
@Override
public void accept(Author author) {
System.out.println(author.getName());
}
});
Stream终结操作符count()
获取流的个数
long count = authors.stream().flatMap(author -> author.getBooks().stream()).distinct().count();
System.out.println(count);
## Stream终结操作符max()和min()
获取流中的最值
//获取最大值
Optional<Integer> max = authors.stream().flatMap(author -> author.getBooks().stream()).map(Book::getScore)
.max(Comparator.comparingInt(o -> o));
System.out.println(max.get());
Stream终结操作符之collect()
把当前的流转换成集合
//获取所有存放作者名字的合集
List<String> list = authors.stream().map(Author::getName).collect(Collectors.toList());
list.forEach(System.out::println);
//获取所有书名的set
Set<String> set = authors.stream().flatMap(author -> author.getBooks().stream()).map(Book::getName).collect(Collectors.toSet());
set.forEach(System.out::println);
//获取键值为作者名,值为书名的map集合,使用匿名内部类实现
Map<String, List<Book>> listMap = authors.stream().collect(Collectors.toMap(new Function<Author, String>() {
@Override
public String apply(Author author) {
return author.getName();
}
}, new Function<Author, List<Book>>() {
@Override
public List<Book> apply(Author author) {
return author.getBooks();
}
}));
listMap.forEach((s, books) -> {System.out.println(s);
books.forEach(book -> System.out.println(book.getName()));
});
//使用lambda表达式实现
Map<String, List<Book>> listMap = authors.stream().collect(Collectors.toMap(Author::getName, Author::getBooks));
listMap.forEach((s, books) -> {System.out.println(s);
books.forEach(book -> System.out.println(book.getName()));
});