Stream流

作用

结合了Lambda表达式,简化集合,数组的操作

步骤

  • 先得到一条Stream流(流水线),并把数据放上去
  • 使用中间方法对流水线上的数据操作
  • 使用终结方法对流水线上的数据操作

获取Stream流

  • 单列集合 -> Collection中的默认方法
1
2
3
4
ArrayList<String> alist = new ArrayList<> ();
Collections.addAll(alist, "a","b","c");
alist.stream()
.forEach(s -> System.out.println(s));
  • 双列集合 -> 无法直接使用stream流
  1. 第一种获取stream流
1
2
3
HashMap<String, Integer> hm = new HashMap<> ();
hm.keySet().stream()
.forEach(s -> System.out.println(s));
  1. 第二种获取stream流
1
2
3
HashMap<String, Integer> hm = new HashMap<> ();
hm.entrySet().stream()
.forEach(s -> System.out.println(s));
  • 数组 -> Arrays工具类中的静态方法
1
2
3
int[] arr = {1, 2, 3, 4};
Arrays.stream(arr)
.forEach(s -> System.out.println(s));
  • 一堆零散数据 -> Stream接口中的静态方法of

注意:方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组,但是数组必须是引用数据类型的,如果传递基本数据类型,是会把整个数组当作一个元素,放到Stream当中

1
2
Stream.of(1, 2, 3, 4, 5)
.forEach(s -> System.out.println(s));

Stream流的中间方法

中间方法,返回新的Stream流,返回的Stream流只能使用一次,因此使用链式编程,修改Stream流中的数据,不会影响原来的集合或者数组中的数据

  • filter 过滤
1
2
3
4
5
6
7
ArrayList<String> list = new ArrayList<> ();
Collections.addAll(list, "abc","abcd","abce","bcd");
list.stream()
.filter(s -> s.startsWith("abc"))
.filter(s -> s.length() == 4)
.forEach(s -> System.out.print(s + " "));
//输出:abdc abce
  • limit 获取前几个元素
1
2
3
4
5
6
ArrayList<String> list = new ArrayList<> ();
Collections.addAll(list, "abc","abcd","abce","bcd");
list.stream()
.limit(3)
.forEach(s -> System.out.print(s + " "));
//输出:abc abcd abce
  • skip 跳过前几个元素
1
2
3
4
5
6
ArrayList<String> list = new ArrayList<> ();
Collections.addAll(list, "abc","abcd","abce","bcd");
list.stream()
.skip(3)
.forEach(s -> System.out.print(s + " "));
//输出:bcd
  • distinct 元素去重,依赖hashCode和equals方法
1
2
3
4
5
6
ArrayList<String> list = new ArrayList<> ();
Collections.addAll(list, "abc","abc","abc","bcd");
list.stream()
.distinct()
.forEach(s -> System.out.print(s + " "));
//输出: abc bcd
  • concat 合并a和b两个流为一个流
1
2
3
4
5
6
7
8
ArrayList<String> list1 = new ArrayList<> ();
ArrayList<String> list2 = new ArrayList<> ();
Collections.addAll(list1, "a");
Collections.addAll(list2, "b");

Stream.concat(list1.stream(), list2.stream())
.forEach(s -> System.out.print(s + " "));
//输出:a b
  • map 转换流中的数据类型
1
2
3
4
5
6
ArrayList<String> list = new ArrayList<> ();
Collections.addAll(list, "abc-3","abcd-4");
list.stream()
.map(s -> Integer.parseInt(s.split("-")[1]))
.forEach(s -> System.out.print(s + " "));
//输出:3 4

Stream流的终结方法

  • forEach 遍历
1
2
3
HashMap<String, Integer> hm = new HashMap<> ();
hm.keySet().stream()
.forEach(s -> System.out.println(s));
  • count 统计长度
1
2
HashMap<String, Integer> hm = new HashMap<> ();
long count = hm.keySet().stream().count();
  • toArray 收集流中的数据,放到数组中
1
2
HashMap<String, Integer> hm = new HashMap<> ();
String[] arr = hm.keySet().stream().toArray(value -> new String[value]);
  • collect 收集流中的数据,放到集合中(List, Set, Map)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ArrayList<String> list = new ArrayList<> ();
Collections.addAll(list, "abc-3","abcd-4");
//收集到List集合中(ArrayList)
List<String> newList = list.stream()
.collect(Collectors.toList());

//收集到Set集合中(HashSet)
Set<String> newSet = list.stream()
.collect(Collectors.toSet());

//收集到Map集合中(HashMap)
//这里键要确保唯一性,否则会报错
Map<String, Integer> newMap = list.stream()
.collect(Collectors.toMap(
s -> s.split("-")[0],
s -> Integer.parseInt(s.split("-")[1])));