一、Stream流的概述
stream流操作是Java 8提供一个重要新特性,它允许开发人员以声明性方式处理集合,其核心类库主要改进了对集合类的 API和新增Stream操作
Stream流的三类方法
-
获取Stream流
- 创建一条流水线,并把数据放到流水线上准备进行操作
-
中间方法
- 流水线上的操作
- 一次操作完毕之后,还可以继续进行其他操作
-
终结方法
- 一个Stream流只能有一个终结方法
-
是流水线上的最后一个操作
二、常用方法
1、stream流创建
- Collection接口的stream()或parallelStream()方法;
- 静态的Stream.of()、Stream.empty()方法;
- Arrays.stream(array, from, to);
- 静态的Stream.generate()方法生成无限流,接受一个不包含引元的函数;
- 静态的Stream.iterate()方法生成无限流,接受一个种子值以及一个迭代函数;
- Pattern接口的splitAsStream(input)方法;
- 静态的Files.lines(path)、Files.lines(path, charSet)方法;
- 静态的Stream.concat()方法将两个流连接起来。
//Collection接口的stream()或parallelStream()方法;
List<String> list = new ArrayList<String>();
Stream<String> listStream = list.stream();
Set<String> set = new HashSet<String>();
Stream<String> setStream = set.stream();
//map可以分别获取Entry、key、value的Stream流
Map<String,Integer> map = new HashMap<String, Integer>();
Stream<String> keyStream = map.keySet().stream();
Stream<Integer> valueStream = map.values().stream();
Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();
//静态的Stream.of()、Stream.empty()方法;
Stream<Object> ofStream = Stream.of();
Stream<Object> emptyStream = Stream.empty();
//Arrays.stream(array, from, to);
IntStream intArrayStream = Arrays.stream(new int[]{1, 2, 3});
//静态的Stream.generate()方法生成无限流,接受一个不包含引元的函数;
Stream<Integer> generateStream = Stream.generate(new Random()::nextInt);
//静态的Stream.iterate()方法生成无限流,接受一个种子值(起始值)以及一个迭代函数(增长操作函数);
Stream<Integer> iterateStream = Stream.iterate(0, x -> x + 1).limit(4);
//Pattern接口的splitAsStream(input)方法;
Stream<String> patternStream = Pattern.compile("ll").splitAsStream("Hello");
try {
//静态的Files.lines(path)、Files.lines(path, charSet)方法;
Stream<String> fileStream = Files.lines(Paths.get("/"));
} catch (IOException e) {
e.printStackTrace();
}
//静态的Stream.concat()方法将两个流连接起来。
Stream<Integer> concatStream = Stream.concat(generateStream, iterateStream);
2、Stream流中间操作
方法名 | 说明 |
---|---|
Stream<T> filter(Predicate predicate) | 用于对流中的数据进行过滤 |
Stream<T> limit(long maxSize) | 返回此流中的元素组成的流,截取前指定参数个数的数据 |
Stream<T> skip(long n) | 跳过指定参数个数的数据,返回由该流的剩余元素组成的流 |
static <T> Stream<T> concat(Stream a, Stream b) | 合并a和b两个流为一个流 |
Stream<T> distinct() | 返回由该流的不同元素(根据Object.equals(Object) )组成的流 |
Stream<T> sorted() | 返回由此流的元素组成的流,根据自然顺序排序 |
Stream<T> sorted(Comparator comparator) | 返回由该流的元素组成的流,根据提供的Comparator进行排序 |
<R> Stream<R> map(Function mapper) | 返回由给定函数应用于此流的元素的结果组成的流 |
3、Stream流终结操
方法名 | 说明 |
---|---|
void forEach(Consumer action) | 对此流的每个元素执行操作 |
long count() | 返回此流中的元素数 |
max() | 返回此流中的最大值 |
min() | 返回此流中的最小值 |
4、Stream流的收集操作
方法名 | 说明 |
---|---|
R collect(Collector collector) | 把结果收集到集合中 |
-
工具类Collectors提供了具体的收集方式`
方法名 说明 public static <T> Collector toList() 把元素收集到List集合中 public static <T> Collector toSet() 把元素收集到Set集合中 public static Collector toMap(Function keyMapper,Function valueMapper) 把元素收集到Map集合中
三、实例
1、Stream流简化过程
ArrayList<String> list = new ArrayList<>();
list.add("张三丰");
list.add("张无忌");
list.add("张翠山");
list.add("王二麻子");
list.add("张良");
list.add("谢广坤");
//1.Predicate接口实现抽象方法test
list.stream().filter(
new Predicate<String>() {
@Override
public boolean test(String s) {
boolean result = s.startsWith("张");
return result;
}
}
).forEach(s-> System.out.println(s));
//2.使用lambda表达式来简化
list.stream().filter(
(String s)->{
boolean result = s.startsWith("张");
return result;
}
).forEach(s-> System.out.println(s));
// 3. Stream流实现
list.stream().filter(s ->s.startsWith("张")).forEach(s-> System.out.println(s));
2、limit&skip& concat&distinct
//创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
//需求1:取前4个数据组成一个流
Stream<String> s1 = list.stream().limit(4);
//需求2:跳过2个数据组成一个流
Stream<String> s2 = list.stream().skip(2);
//需求3:合并需求1和需求2得到的流,并把结果在控制台输出
// Stream.concat(s1,s2).forEach(s-> System.out.println(s));
//需求4:合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复
Stream.concat(s1,s2).distinct().forEach(s-> System.out.println(s));
//需求5:返回所有姓张的
list.stream().map(s -> {
return s.startsWith("张");
}).forEach(s-> System.out.println(s));
//需求6:进行排序
list.stream().sorted((o1, o2) -> o1.compareTo(o2) ).forEach(s-> System.out.println(s));
3、收集操作toSet& toList
ArrayList<Integer> list1 = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
list1.add(i);
}
for (int i = 1; i <= 4; i++) {
list1.add(10);
}
//filter负责过滤数据的.
//collect负责收集数据.
//获取流中剩余的数据,但是他不负责创建容器,也不负责把数据添加到容器中.
//Collectors.toList() : 在底层会创建一个List集合.并把所有的数据添加到List集合中.
List<Integer> list = list1.stream().filter(number -> number % 2 == 0)
.collect(Collectors.toList());
System.out.println(list);
Set<Integer> set = list1.stream().filter(number -> number % 2 == 0)
.collect(Collectors.toSet());
System.out.println(set);
4、收集操作toMap
ArrayList<String> list = new ArrayList<>();
list.add("张三,23");
list.add("李四,24");
list.add("王五,25");
// collect方法只能获取到流中剩余的每一个数据.
//在底层不能创建容器,也不能把数据添加到容器当中
//Collectors.toMap 创建一个map集合并将数据添加到集合当中
Map<String, Integer> map = list.stream().filter(
// s 依次表示流中的每一个数据
s -> {
String[] split = s.split(",");
int age = Integer.parseInt(split[1]);
return age >= 24;
}
).collect(Collectors.toMap(
//第一个lambda表达式就是如何获取到Map中的键
//第二个lambda表达式就是如何获取Map中的值
s -> s.split(",")[0],
s -> Integer.parseInt(s.split(",")[1]) )
);
System.out.println(map);
网友评论