简介
Stream流作用
结合Lambda表达式,简化集合、数组的操作
Stream流的使用步骤
- 先得到一条Stream流,将数据放上去
- 使用中间方法对流水线上的数据进行操作
- 使用终结方法对流水线上的数据进行操作
获取Stream流
获取方式 | 方法名 | 说明 |
---|---|---|
单列集合 | default Stream<E> stream() | Collection中的默认方法 |
双列集合 | 无 | 需要转换成单列集合才能获取Stream流 |
数组 | public static<T> Stream<T> stream(T[] array) | Arrays工具类中的静态方法 |
零散数据 | public static<T> Stream<T> of(T... values) | Stream接口中的静态方法 |
单列集合获取Stream流
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
// 向list中添加数据
Collections.addAll(list,"a","b","c");
// 1. 获取流
// 2. 调用流的forEach方法
// 3. 使用lambda表达式,对每一个参数s,执行打印操作
list.stream().forEach(s -> System.out.println(s));
}
双列集合获取Stream流
public static void main(String[] args) {
HashMap<String,Integer> map = new HashMap<>();
// 添加数据
map.put("aaa",111);
map.put("bbb",222);
map.put("ccc",333);
// 获取单列集合keySet,然后再获取流
map.keySet().stream().forEach(s -> System.out.println(s));
//aaa
//ccc
//bbb
// 获取单列集合entrySet(),然后再获取流
map.entrySet().stream().forEach(s -> System.out.println(s));
//aaa=111
//ccc=333
//bbb=222
}
数组获取Stream流
public static void main(String[] args) {
// 基本数据类型
int[] arr1 = {1,2,3,4};
// 引用数据类型
String[] arr2 = {"a","b","c"};
// 获取Stream流
Arrays.stream(arr1).forEach(s -> System.out.println(s));
Arrays.stream(arr2).forEach(s -> System.out.println(s));
}
零散数据获取Stream流
public static void main(String[] args) {
// 基本数据类型
Stream.of(1,2,3,4).forEach(s -> System.out.println(s));
// 引用数据类型
Stream.of("aa","bb","cc","dd").forEach(s -> System.out.println(s));
}
注意:
Stream接口中静态方法of
的细节方法的形参是一个可变参数,可以传递一堆零散数据,也可传递数组
但是数组必须是引用数据类型,如果是基本数据类型,会把整个数组当作一个元素,放入Stream中
public static void main(String[] args) {
// 基本数据类型
int[] arr1 = {1,2,3,4};
// 引用数据类型
String[] arr2 = {"a","b","c"};
Stream.of(arr1).forEach(s -> System.out.println(s));
// [I@404b9385
Stream.of(arr2).forEach(s -> System.out.println(s));
// a
// b
// c
}
Stream流的中间方法
注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,推荐使用链式编程
注意2:修改Stream流中的数据,不会影响原来集合或者数组中的数据
filter过滤
static void testFilter(){
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白展堂","吕秀才","佟湘玉","郭芙蓉","祝无双","李大嘴","白瓜");
// filter 过滤
list.stream().filter(s -> s.startsWith("白")).forEach(s -> System.out.println(s));
}
白展堂
白瓜
limit获取前几个元素
static void testLimit(){
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白展堂","吕秀才","佟湘玉","郭芙蓉","祝无双","李大嘴","白瓜");
// limit获取前3个元素
list.stream().limit(3).forEach(s -> System.out.println(s));
}
白展堂
吕秀才
佟湘玉
skip跳过前几个元素
static void testSkip(){
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白展堂","吕秀才","佟湘玉","郭芙蓉","祝无双","李大嘴","白瓜");
// skip跳过前3个元素,再取前2个
list.stream().skip(3).limit(2).forEach(s -> System.out.println(s));
}
郭芙蓉
祝无双
distinct去重
static void testDistinct(){
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白展堂","白展堂","白展堂","吕秀才","佟湘玉","郭芙蓉","祝无双","李大嘴","白客");
// distinct元素去重
list.stream().distinct().forEach(s -> System.out.println(s));
}
白展堂
吕秀才
佟湘玉
郭芙蓉
祝无双
李大嘴
白客
concat合并Stream流
static void testConcat(){
ArrayList<String> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list1,"白展堂","祝无双","李大嘴","白客");
Collections.addAll(list2,"莫言","刘慈欣");
// concat连接两个stream流
Stream.concat(list1.stream(),list2.stream()).forEach(s -> System.out.println(s));
}
白展堂
祝无双
李大嘴
白客
莫言
刘慈欣
map转换流中的数据类型
static void testMap(){
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白展堂-18","郭芙蓉-19","祝无双-17","李大嘴-20");
// map转换流中数据
list.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(s -> System.out.println(s));
}
18
19
17
20
Stream流的终结方法
forEach遍历
count统计
static void testCount(){
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白展堂","祝无双","李大嘴","白客");
System.out.println(list.stream().count());
}
toArray收集流中的数据到数组
toArray()方法的参数作用:创建一个指定类型指定大小的数组
如果调用无参的toArray()方法,将会创建Object类型数组
static void testToArray(){
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白展堂","祝无双","李大嘴","白客");
String[] array = list.stream().toArray(value -> new String[value]);
System.out.println(Arrays.toString(array));
}
[白展堂, 祝无双, 李大嘴, 白客]
collect收集流中的数据到集合
收集数据到List
static void testCollect1(){
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白展堂-男-18","郭芙蓉-女-19","祝无双-女-17","李大嘴-男-20");
// 收集所有男性
// 静态方法Collectors.toList()生成一个ArrayList集合
List<String> list1 = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toList());
System.out.println(list1);
}
[白展堂-男-18, 李大嘴-男-20]
收集数据到Set
static void testCollect2(){
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白展堂-男-18","郭芙蓉-女-19","祝无双-女-17","李大嘴-男-20");
// 收集所有男性
// 静态方法Collectors.toSet()生成一个HashSet
Set<String> list2 = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toSet());
System.out.println(list2);
}
Set中不允许出现重复数据
收集数据到Map
static void testCollect3(){
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白展堂-男-18","郭芙蓉-女-19","祝无双-女-17","李大嘴-男-20");
// 收集所有男性,键为姓名,值为年龄
// 静态方法Collectors.toMap()生成一个HashMap
Map<String, Integer> map = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(
s -> s.split("-")[0],
s -> Integer.parseInt(s.split("-")[2]))
);
System.out.println(map);
}
{白展堂=18, 李大嘴=20}
Map的keyset不允许重复
toMap()中参数一定义生成键的规则,参数二定义生成值的规则