每一秒钟的时间都值得铭记

0%

JDK8新特性之Stream流

什么是Stream流?

Stream流是JDK8中的一个全新的概念,用于解决已有集合类库既有的弊端。

传统集合遍历的弊端

  • 每当我们需要对集合中的元素进行操作的时候,总是需要循环、循环、再循环,循环是遍历集合的方式,而不是目的,我们的目的是将集合中的元素全部都处理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("我爱中国");
list.add("第二元素");
list.add("第三元素");
list.add("东西南北");
list.add("碳元素");
//对list集合中的元素进行过滤,将包含"元素"的元素放入listA集合
List<String> listA = new ArrayList<String>();
for (String str : list) {
if(str.contains("元素")) {
listA.add(str);
}
}
//对listA集合中的元素进行过滤,将包含"三"的元素放入listB集合
List<String> listB = new ArrayList<String>();
for (String str : listA) {
if(str.contains("三")) {
listB.add(str);
}
}
//遍历listB集合,输出元素
for (String str : listB) {
System.out.println(str);
}
}

Stream的方式

  • 使用Stream流的方式,可以更简单高效的方式处理集合。
1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("我爱中国");
list.add("第二元素");
list.add("第三元素");
list.add("东西南北");
list.add("碳元素");

list.stream()
.filter(name->name.contains("元素"))
.filter(name->name.contains("三")).forEach(name->System.out.println(name));
}

两种获取Stream流的方式

java.util.stream.Stream是JDK8新加入的最常用的流接口(这不是一个函数式接口)。

  • 所有Collection集合都可以通过stream默认方法获取流。
  • Stream接口中的静态方法of可以获取数组对应的流。

根据stream()方法获取流

Collection接口中有一个默认方法stream(),所有Collection集合都可以通过这个方法来获取流。

  • Map集合无法直接通过这种方式获取流。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//List集合获取流对象
List<String> list = new ArrayList<String>();
Stream<String> stream1 = list.stream();

//Set集合获取流对象
Set<String> set = new HashSet<String>();
Stream<String> stream2 = set.stream();

//通过Map集合的keySet获取流对象
Map<String, String> map = new HashMap<String, String>();
//获取map集合的键stream流
Set<String> keySet = map.keySet();
Stream<String> stream3 = keySet.stream();
//获取map集合的值stream流
Collection<String> values = map.values();
Stream<String> stream4 = values.stream();
//获取map集合键值对的stream流
Set<Entry<String, String>> entries = map.entrySet();
Stream<Entry<String, String>> stream5 = entries.stream();

根据of()方法获取流

Stream接口中的静态方法of(),参数是一个可变参数。

1
2
3
4
5
6
7
8
//直接传入可变数组
Stream<Integer> stream6 = Stream.of(1,2,3,4,5,6);
//传入一个整形数组
Integer[] arr1 = {1,2,3,4,5,6};
Stream<Integer> stream7 = Stream.of(arr1);
//传入一个字符串数组
String[] arr2 = {"a","bb","ccc"};
Stream<String> stream8 = Stream.of(arr2);

Stream流中的常用方法

Stream流中的方法被分成两种:

  • 延迟方法: 返回值类型仍然是Stream流接口自身类型的方法,因此支持链式编程(除了终结方法外,其余方法均为延迟方法)。
  • 终结方法: 返回值类型不再是Stream流接口自身类型的方法,因此不再支持链式编程调用。

延迟方法

过滤:filter

1
Stream<T> filter(Predicate<? super T> predicate);
  • 代码示例:
1
2
3
Stream<String> stream1 = Stream.of("张三","李四","王五");
Stream<String> stream2 = stream1.filter(name->name.startsWith("张"));
stream2.forEach(name->System.out.println(name));

映射: map

1
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
  • 代码示例:
1
2
3
Stream<String> stream1 = Stream.of("1","2","3");
Stream<Integer> stream2 = stream1.map(str->Integer.parseInt(str));
stream2.forEach(i->System.out.println(i));

切割前几个元素:limit

1
Stream<T> limit(long maxSize);
  • 代码示例:
1
2
3
Stream<String> stream1 = Stream.of("1","2","3","4","5");
Stream<String> stream2 = stream1.limit(3);
stream2.forEach(str->System.out.println(str));

跳过前几个元素:skip

1
Stream<T> skip(long n);
  • 代码示例:
1
2
3
Stream<String> stream1 = Stream.of("1","2","3","4","5");
Stream<String> stream2 = stream1.skip(3);
stream2.forEach(str->System.out.println(str));

组合:concat

1
2
3
4
Stream<String> stream1 = Stream.of("美羊羊","懒羊羊");
Stream<String> stream2 = Stream.of("灰太狼","红太狼");
Stream<String> stream3 = Stream.concat(stream1, stream2);
stream3.forEach(str->System.out.println(str));

终结方法

逐一处理:forEach

1
void forEach(Consumer<? super T> action);
  • 代码示例:
1
2
3
4
public static void main(String[] args) {
Stream<String> stream = Stream.of("张三","李四","王五");
stream.forEach(name->System.out.println(name));
}

统计个数:count

1
long count();
  • 代码示例:
1
2
3
Stream<String> stream = Stream.of("1","2","3");
long count = stream.count();
System.out.println(count);

Stream流属于管道流

Stream流属于管道流,只能被消费(使用)一次,第一个Stream流调用完毕方法,数据就会流转到下一个Stream上,而这时第一个Stream流已经使用完毕,就会关闭流,所以第一个Stream流就不能调用方法了。

1
2
3
4
5
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("张三","李四","王五");
Stream<String> stream2 = stream1.filter(name->name.startsWith("张"));
stream1.forEach(name->System.out.println(name));
}
  • 以上代码编译通过,但是执行后爆出stream流已经关闭的异常。
1
java.lang.IllegalStateException: stream has already been operated upon or closed
坚持原创技术分享,您的支持将鼓励我继续创作!
-------------这是我的底线^_^-------------