1、流的创建
1.1、 使用集合对象的 stream() 方法创建流
- 数组对象,创建流时需要使用
Arrays.stream()
方法; - 集合类对象,可以在对象后直接使用
.stream()
方法转换为流; - Map 对象不能直接转换为流,但是可以对 Map 对象中的 key 、 value、 entrySet 分别转换为流方便后续使用。
//数组对象
int[] ints = new int[]{1,3,5,7,11};
IntStream stream = Arrays.stream(ints);
//List对象转换为流
List<Integer> nums = Arrays.asList(6,9,15,32,48);
Stream<Integer> stream1 = nums.stream();
//Map对象
Map<String, String> map = new Hashtable<>();
map.put("one", "first");
map.put("two", "second");
Stream<String> keys = map.keySet().stream();
Stream<String> values = map.values().stream();
Stream<Map.Entry<String, String>> stream3 = map.entrySet().stream();
复制代码
1.2、 使用 Stream.of() 方法创建流
对于数组来说,还可以通过 Stream.of() 方法转换为流
Stream<Integer> ints1 = Stream.of(1,3,5,7,11);
复制代码
对于其他非数组的对象来说,这种方式,可能会将问题变得复杂,不如第一种简便。
2、流的中间操作
中间操作: 中间操作会返回一个新的流,一个流的后面可以跟随零个或多个其他中间操作,成为一个操作链。
中间操作的主要目的是打开流,做出某种数据映射或者过滤,然后会返回一个新的流,交给下一个操作使用。
这类操作都是惰性化的,仅仅调用到这类方法,并没有真正开始流的遍历。而是在执行到结束操作开始的时候才真正开始执行。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Stream1 {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(6,9,15,32,48);
//filter() 返回结果生成新的流中只包含满足筛选条件的数据
List<Integer> results = nums.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());
System.out.println(results);
}
}
复制代码
输出结果:
[6, 32, 48]
示例中:
- stream() 是创建操作,通过该操作可以将集合对象转换为流;
- filter() 是中间操作,在这里的作用是从列表中过滤出能被2整除的数据后,生成新的流;
- collect() 是结束操作,这里是将前边生成的新流收集成为一个新的列表。
2.1、filter 操作
filter 是 Stream 流中的常用方法,主要用于对 Stream 流中的数据进行过滤,便于对过滤后的流进行后续其他操作。 filter 方法的参数 Predicate 是一个函数式接口,所以可以传递 Lambda 表达式,对数据进行操作。
筛选出列表中内容包含字母 a 的元素并输出:
@Test
public void testFilter(){
Stream<String> stream = Stream.of("lisi", "zhangsan", "wangwu");
stream.filter(name -> name.contains("a")).forEach(System.out::println);
}
复制代码
输出结果如下:
zhangsan
wangwu
2.2、sorted 操作
Stream的sorted()排序,能够以自然顺序或者用 Comparator 接口定义的排序规则来排序一个流,Comparator 能用 lambda 表达式来初始化,还能够逆序一个已经排序的流。
@Test
public void testSorted(){
List<String> list = Arrays.asList("lisi", "zhangsan", "wangwu", "anhui");
System.out.println("==========正序排序");
list.stream().sorted().forEach(System.out::println);
System.out.println("==========倒序排序");
list.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println);
}
复制代码
在倒序排序时,使用了 Comparator.reverseOrder() 静态方法,对流进行了翻转。 输出结果:
==========正序排序
anhui
lisi
wangwu
zhangsan
==========倒序排序
zhangsan
wangwu
lisi
anhui
2.3、 limit 操作
用于截取流中的元素,limit方法可以对流进行截取,只取用前n个。
对列表元素正序排序后,取出前两个元素。
@Test
public void testLimit(){
List<String> list = Arrays.asList("lisi", "zhangsan", "wangwu", "anhui");
list.stream().sorted().limit(2).forEach(System.out::println);
}
复制代码
输出结果:
anhui
lisi
2.4、 distinct 操作
Stream流中的 distinct 方法用于去除流中的重复元素。
Stream流的 distinct 方法如果要对自定义对象去重,定义的对象需要实现hashcode()和 equals()方法。
@Test
public void testLimit(){
List<String> list = Arrays.asList("lisi", "zhangsan", "lisi", "anhui");
list.stream().distinct().forEach(System.out::println);
}
复制代码
输出结果:
lisi
zhangsan
anhui
2.5、 skip 操作
用于跳过元素,如果希望跳过前几个元素,可以使用skip方法获取一个截取之后的新流。
对流中的元素排序后,取出除第一个元素外的其它元素:
@Test
public void testLimit(){
List<String> list = Arrays.asList("lisi", "zhangsan", "wangwu", "anhui");
list.stream().sorted().skip(1).forEach(System.out::println);
}
复制代码
输出结果:
lisi
wangwu
zhangsan