一、问题分析
1、集合处理数据的弊端
- 在需要对集合中的元素进行操作时,集合遍历是典型的操作
package com.my.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class StreamTest1 {
public static void main(String[] args) {
List<String> list = Arrays.asList("jack", "tom", "smith", "mery");
System.out.println(list);
// 获取名称中有 t 的用户
ArrayList<String> arrayList1 = new ArrayList<>();
for (String s : list) {
if (s.contains("t")) {
arrayList1.add(s);
}
}
System.out.println(arrayList1);
// 获取名称长度为 4 的用户
ArrayList<String> arrayList2 = new ArrayList<>();
for (String s : list) {
if (s.length() == 4) {
arrayList2.add(s);
}
}
System.out.println(arrayList2);
}
}
2、解决方案
- 针对不同的需求总是会进行遍历操作,可以通过 Stream API 进行高效处理
package com.my.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class StreamTest2 {
public static void main(String[] args) {
List<String> list = Arrays.asList("jack", "tom", "smith", "mery");
System.out.println(list);
// 获取名称中有 t 的用户
ArrayList<String> arrayList1 = new ArrayList<>();
list.stream()
.filter(s -> s.contains("t"))
.forEach(s -> arrayList1.add(s));
System.out.println(arrayList1);
// 获取名称长度为 4 的用户
ArrayList<String> arrayList2 = new ArrayList<>();
list.stream()
.filter(s -> s.length() == 4)
.forEach(s -> arrayList2.add(s));
System.out.println(arrayList2);
}
}
二、Stream 的获取方式
1、Collection 的默认方法 stream
(1)基本介绍
- java.util.Collection 接口中存在默认方法 stream
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
(2)演示
- 所有 Collection 接口的实现都可以通过 stream 方法来获取 Stream
ArrayList<Object> arrayList = new ArrayList<>();
Stream<Object> stream1 = arrayList.stream();
System.out.println(stream1);
HashSet<Object> hashSet = new HashSet<>();
Stream<Object> stream2 = hashSet.stream();
System.out.println(stream2);
Vector<Object> vector = new Vector<>();
Stream<Object> stream3 = vector.stream();
System.out.println(stream3);
- Map 接口实现获取 Stream
HashMap<Object, Object> hashMap = new HashMap<>();
Stream<Object> stream4 = hashMap.keySet().stream();
System.out.println(stream4);
Stream<Object> stream5 = hashMap.values().stream();
System.out.println(stream5);
Stream<Map.Entry<Object, Object>> stream6 = hashMap.entrySet().stream();
System.out.println(stream6);
2、Stream 的静态方法 of
(1)基本介绍
- 在实际开发中会不可避免的使用到数组操作,Stream 接口中提供了默认方法 of 来对数组进行相关操作
public static<T> Stream<T> of(T t) {
return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
}
@SafeVarargs
@SuppressWarnings("varargs") // Creating a stream from an array is safe
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
(2)演示
- 数组获取 Stream
Stream<String> stream1 = Stream.of("a1", "a2", "a3");
System.out.println(stream1);
String[] arr1 = {
"aa", "bb", "cc"};
Stream<String> stream2 = Stream.of(arr1);
System.out.println(stream2);
// 不能使用基本数据类型的数组
Integer[] arr2 = {
1, 2, 3, 4};
Stream<Integer> stream3 = Stream.of(arr2);
System.out.println(stream3);
三、Stream 方法概述
1、终结方法
-
返回值不是 Stream 类型的方法,不再支持链式调用
-
终结方法包括 forEach、count、match 方法
2、非终结方法
-
返回值是 Stream 类型的方法,支持链式调用
-
除了终结方法外,其余方法均为非终结方法
四、Stream 常用方法
1、forEach 方法
(1)基本介绍
- 用来遍历流中的元素
void forEach(Consumer<? super T> action);
- 该方法接收一个 Consumer 函数式接口,将流中每一个元素交给 Consumer 处理
(2)演示
Stream<String> stream = Stream.of("a1", "a2", "a3");
stream.forEach(s -> {
System.out.println(s);
});
2、count 方法
(1)基本介绍
- 用来统计流中元素的个数
long count();
(2)演示
Stream<String> stream = Stream.of("a1", "a2", "a3");
long count = stream.count();
System.out.println(count);
3、filter 方法
(1)基本介绍
- 过滤流中的元素
Stream<T> filter(Predicate<? super T> predicate);
- 该方法接收一个 Predicate 函数式接口,将流中每一个元素交给 Predicate 处理
(2)演示
Stream<String> stream = Stream.of("a1", "a2", "a3");
stream.filter(s -> {
return s.contains("1");
}).forEach(s -> {
System.out.println(s);
});
4、limit 方法
(1)基本介绍
- 可以对流中的元素进行截取,只取前 N 个元素
Stream<T> limit(long maxSize);
(2)演示
stream.limit(2).forEach(s -> System.out.println(s)