JAVA JDK8新概念Stream流及操作集合案例

在Jdk1.8中引入了stream流的概念,这个“流”并不同于IO中的输入和输出流,它是Jdk中的一个类:java.util.stream.Stream,使用流进行处理可以帮助我们提升代码的性能。

1. 常见应用

使用Stream流对集合进行过滤和遍历操作:

import java.util.ArrayList;
import java.util.List;
public class Demo{
	public static void main(String[]args){
		List<String> list =new ArrayList<>();
		list.add("张三");
		list.add("李四");
		list.add("王五五");
		list.add("张强");
		list.add("张无忌");
		list.stream()
			//只要以"张"开头的
			.filter(s‐>s.startsWith("张"))
			//只要长度为3的
			.filter(s‐>s.length()==3)//forEach中传入Consumer接口的实现类,使用Lambda表达式的方法引用写法
			.forEach(System.out::println);
	}
}

2. 流的获取

2.1 Stream.of()

java.util.stream.Stream<T>是Java8新加入的最常用的流接口。(这并不是一个函数式接口。)
获取一个流非常简单,有以下几种常用的方式:
所有的Collection集合都可以通过stream默认方法获取流;
Stream接口的静态方法of可以获取数组对应的流。

//获取数组的流
int[] array = new int[10];
Stream<int[]> arrayStream = Stream.of(array);

//获取List的流,当然,对于集合的流有更简单的获取方式
List<String> list = new ArrayList<>();
Stream<List<String>> listStream = Stream.of(list);

2.2 XXX.stream()

Collection获取流

java.util.Collection接口中加入了default方法stream用来获取流,所以其所有实现类均可获取流。

public static void main(String[]args){
	List<String> list = new ArrayList<>();
	//...
	Stream<String> stream1 = list.stream();
	Set<String> set = new HashSet<>();
	//...
	Stream<String> stream2 = set.stream();
	Vector<String> vector=new Vector<>();
	//...
	Stream<String> stream3 = vector.stream();
}

Map获取流

java.util.Map接口不是Collection的子接口,且其K-V数据结构不符合流元素的单一特征,所以获取对应的流需要分key、value或entry等情况:

public static void main(String[]args) {
	Map<String,String> map = new HashMap<>();
	//...
	Stream<String> keyStream = map.keySet().stream();
	Stream<String> valueStream = map.values().stream();
	Stream<Map.Entry<String,String>> entryStream = map.entrySet().stream();
}

3. 流的常用方法

流模型的操作方法很多,这里介绍一些常用的。这些方法可以被分成两种:

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

3.1 forEach

void forEach(Consumer<?superT> action);
该方法接收一个Consumer接口函数,会将每一个流元素交给该函数进行处理。
可以用实现类的方式重写Consumer接口的accep方法实现消费逻辑,更简单的方式是直接使用Lambda表达式:

public static void main(String[]args){
	Stream<String> stream = Stream.of("aaa","bbb","ccc");
	stream.forEach(name ‐> System.out.println(name));
}

还可以利用方法引用进一步简化Lambda表达式

stream.forEach(System.out :: println);

方法引用简化规则解析请参考另一篇博客:
链接: JAVA Lambda表达式使用方法引用优化.

3.2 filter

Stream<T> filter(Predicate<?superT> predicate);

该接口接收一个Predicate函数式接口,可以实现该接口并重写test方法实现过滤逻辑。test()方法将会产生一个boolean值结果,代表指定的条件是否满足。如果结果为true,那么Stream流的filter方法将会留用元素;如果结果为false,那么filter方法将会舍弃元素。
当然简单的写法还是使用Lambda:

扫描二维码关注公众号,回复: 9987275 查看本文章
public static void main(String[]args){
	Stream<String> original = Stream.of("张三","张四","王五");
	Stream<String> result = original.filter(s->s.startsWith("张"));
}

3.3 map

map方法可以将流中的元素映射到另一个流中。

<R>Stream<R> map(Function<? super T, ? extends R> mapper);

该接口需要一个Function函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流。可以实现该接口并重写apply方法实现映射逻辑。

当然简单的写法还是使用Lambda:

public static void main(String[]args){
	Stream<String> original = Stream.of("10","12","18");
	Stream<Integer> result = original.map(str‐>Integer.parseInt(str));
}

3.4 count

流提供count方法来获取其中的元素个数。

long count();
直接获取:

public static void main(String[]args){
	Stream<String> original = Stream.of("10","12","18");
    long n = original.count();
}

3.4 limit

流提供limit方法来获取前几个元素。

Stream<T> limit(long maxSize);
参数是一个long型,如果集合当前长度大于参数则进行截取;否则不进行操作。基本使用:

public static void main(String[]args){
	Stream<String> original = Stream.of("10","12","18");
    Stream<String> limit = original.limit(2);
    System.out.println(limit.count());//结果:2
}

3.5 skip-跳过前几个

Stream<T> skip(long n);

如果流的当前长度大于n,则跳过前n个;否则将会得到一个长度为0的空流。基本使用:

public static void main(String[]args){
	Stream<String> original = Stream.of("10","12","18");
    Stream<String> limit = original.skip(2);
    System.out.println(limit.count());//结果:1
}

3.6 concat-合并流

static<T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)

该方法的基本使用代码如下:

import java.util.stream.Stream;
public class Demo{
	public static void main(String[]args){
		Stream<String> streamA = Stream.of("AAA");
		Stream<String> streamB = Stream.of("BBB");
		Stream<String> result = Stream.concat(streamA, streamB);
	}
}
发布了16 篇原创文章 · 获赞 6 · 访问量 796

猜你喜欢

转载自blog.csdn.net/weixin_43838446/article/details/104951456