jdk1.8新特性之Stream流?妖怪吧!
jdk1.8新特性之Stream流
首先,我们来看一下这个小练习:
一个ArrayList集合中存储有以下数据:张无忌,周芷若,赵敏,张强,张三丰
需求:1.拿到所有姓张的 2.拿到名字长度为3个字的 3.打印这些数据
我们可以这样做:
public class Demo10 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");
// 需求:1.拿到所有姓张的
ArrayList<String> zhangList = new ArrayList<>();
for (String name : list) {
if (name.startsWith("张")) {
zhangList.add(name);
}
}
// 2.拿到名字长度为3个字的
ArrayList<String> threeList = new ArrayList<>();
for (String name : zhangList) {
if (name.length() == 3) {
threeList.add(name);
}
}
// 3.打印这些数据
for (String name : threeList) {
System.out.println(name);
}
}
}
OK,搞定收工!
是,是搞定了,但是你有没有发现上述代码一直都在遍历集合,麻烦!
接下来我这样做:
public class Demo10 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");
list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
}
}
是不是心里顿时不平衡了…哈哈
Stream流的作用:对数据进行加工处理
Stream流介绍: 流式编程思想,重点是对数据进行加工处理
Stream流的使用2个步骤:
- 1.获取Stream流
- 2.调用Stream流的方法加工处理数据
获取流的两种方式:
方式1:Collection接口就有获取Stream流的方法:
default Stream stream() 根据Collection获取流
import java.util.*;
import java.util.stream.Stream;
public class Demo04GetStream {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
// ...
Stream<String> stream1 = list.stream();
Set<String> set = new HashSet<>();
// ...
Stream<String> stream2 = set.stream();
Vector<String> vector = new Vector<>();
// ...
Stream<String> stream3 = vector.stream();
}
}
根据map集合获取流
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public class Demo05GetStream {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
// ...
Stream<String> keyStream = map.keySet().stream();
Stream<String> valueStream = map.values().stream();
Stream<Map.Entry<String, String>> entryStream =
map.entrySet().stream();
}
}
方式2:Stream类静态方法of() 根据数组获取流
import java.util.stream.Stream;
public class Demo06GetStream {
public static void main(String[] args) {
String[] array = { "张无忌", "张翠山", "张三丰", "张一元" };
Stream<String> stream = Stream.of(array);
}
}
Stream流的常用方法:
终结方法:返回值类型不再是 Stream 接口自身类型的方法,因此不再支持类似StringBuilder 那样的链式调用。本小节中,终结方法包括 count 和 forEach 方法。
非终结方法(函数拼接方法):返回值类型仍然是 Stream 接口自身类型的方法,因此支持链式调用。(除了终结方法外,其余方法均为非终结方法。)
我们使用Stream可以对数据进行处理.处理后怎么办?count?forEach?
不,是将Stream流中的数据重新放回集合或数组中
将流中的内容收集到集合中
- stream.collect(Collectors.toList());
- stream.collect(Collectors.toSet());
将流中的内容收集到数组中
- stream.toArray();
public class Demo2 {
public static void main(String[] args) {
Stream<String> stream = Stream.of("张三", "李四", "王五");
// 假设stream一顿操作后,将结果收集到集合中
// List<String> list = stream.collect(Collectors.toList());
// System.out.println("list = " + list);
// Set<String> set = stream.collect(Collectors.toSet());
// System.out.println("set = " + set);
Object[] objects = stream.toArray();
for (Object object : objects) {
System.out.println(object);
}
}
}
Stream注意事项:
- 1)一个Stream流只能调用一次方法
- 2)Stream流调用返回的是新的Stream流
- 3)Stream流必须调用终结方法,否则不执行
如何获取并发流?
list.stream() 普通流
list.parallelStream() 并发流
list.stream().paralle() 将普通流转成并发流
public class Demo22 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
// 并发流
list.parallelStream().forEach(new Consumer<String>() {
@Override
public void accept(String s) {
Thread thread = Thread.currentThread();
String name = thread.getName();
System.out.println("name: " + name);
}
});
// 普通流转成并发流
Stream<String> stream = list.stream();
stream.parallel().forEach(new Consumer<String>() {
@Override
public void accept(String s) {
String name = Thread.currentThread().getName();
System.out.println("name1: " + name);
}
});
}
}