当我们需要对集合中的元素进行操作的时候,除了必须的添加,删除,获取外,最经典的就是集合遍历 Stream流的含义: 获取流,过滤流张,过滤长度,注意打印,使得代码更加的简介直观。一、Stream流的获取方式 通过collection获取
List list = Arrays.asList(1,2,3,4,5,6); Stream stream = list.stream();
map接口没有实现Collection接口,这时我们可以根据Map获取对应的key,value的集合。
Map map = new HashMap(); Stream stream = map.keySet().stream(); Collection values = map.values(); Stream stream1 = values.stream();通过Stream的of方法
在实际开发中我们不可避免的还会操作到数组中的数据。由于数组中不可能添加默认的方法,所以Stream流提供了静态方法of
// 方式1
Integer[] nums = {1,2,3,4,5,6,7};
Stream nums1 = Stream.of(nums);
// 方式2
Stream integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7)
二、Stream常用方法介绍
| 方法名 | 方法作用 | 返回值类型 | 方法种类 |
|---|---|---|---|
| count | 统计个数 | long | 终结 |
| forEach | 逐一处理 | void | 终结 |
| filter | 过滤 | Stream | 函数拼接 |
| limit | 取用前几个 | Stream | 函数拼接 |
| skip | 跳过前几个 | Stream | 函数拼接 |
| map | 映射 | Stream | 函数拼接 |
| concat | 组合 | Stream | 函数拼接 |
终结方法,不支持链式调用
非终结方法,仍然是Stream流,支持链式调用。
注意
Stream只能操作一次
Stream返回的是一个新的流
Stream不调用终结方法的话,那么他是不会执行的。
用于遍历流中的数据
void forEach(Consumer super T> action);
该方法接收一个Consumer接口,会将每一个流元素交给函数处理。
Stream.of(1,2,3).forEach(System.out::println);2、count方法
Stream流中的count方法用来统计其中的元素个数。
long count = Stream.of(1, 2, 3).count();3、 filter方法
filter方法的作用是用来过滤数据的,返回符合条件的数据。
Streamfilter (Predicate super T> predicate);
该接口接收一个Predicate函数式接口参数作为筛选条件。
Stream.of(1,2,3).filter(s -> {
return s>=2? true:false;
}).forEach(s->{
System.out.println(s);
});
4、limit方法
可以对流进行截取处理,只取出前几个数据。
Streamlimit(long maxSize)
Stream.of(1,2,3).limit(2).forEach(System.out::println);5、 skip方法
如果希望跳过前几个元素,可以使用skip方法获取一个截取之后的流。
Streamskip (long n);
Stream.of(1,2,3).skip(1).forEach(System.out::println);6、map方法
如果我们需要将流中的元素映射到另一个流中,可以使用map方法。
Stream map(Function super T, ? extends R> mapper);
可以将流中T型的数据,转换为R类型的数据。
Stream.of("1","2","3")
.map(Integer::parseInt)
.forEach(System.out::println);
Stream.of("a","b","c").map(s->{
return s + "123";
}).forEach(System.out::println);
7、sorted方法
如果需要将数据进行排序,可以使用该方法
Streamsorted();
Stream.of("1","2","3")
.map(Integer::parseInt)
.sorted()
.forEach(System.out::println);
Optional8、distinct方法max = Stream.of("2", "1", "3", "3") .map(Integer::parseInt) .sorted((a,b) -> a -b) .findFirst(); System.out.println(max.get());
如果要是重复数据,可以使用distinct方法
他的是否相同是通过equals方法来进行判断的
Streamdistinct();
Stream.of("1","2","3","3")
.map(Integer::parseInt)
.distinct()
.forEach(System.out::println);
9、match方法
如果需要判断数据是否符合指定的条件,可以使用match相关的方法。
boolean anyMatch(Rredicate super T> predicate); //元素是否有任意一个满足条件 boolean allMatch(Rredicate super T> predicate); //元素是否都满足条件 boolean noneMatch(Rredicate super T> predicate); //元素是否都不满足条件
boolean b = Stream.of("1", "2", "3", "3")
.map(Integer::parseInt)
.allMatch(s -> s > 0);
boolean b = Stream.of("1", "2", "3", "3")
.map(Integer::parseInt)
.anyMatch(s -> s > 2);
boolean b = Stream.of("1", "2", "3", "3")
.nonemap(Integer::parseInt)
.anyMatch(s -> s > 2);
match是一个终结方法
10、max和min方法如果我么想要获取最大值和最小值,那么可以使用max和min方法。
Optional11、reduce方法max = Stream.of("1", "2", "3", "3") .map(Integer::parseInt) .max((a, b) -> a - b); System.out.println(max.get());
如果需要将所有数据归纳得到一个数据,可以使用reduce方法。
Integer reduce = Stream.of("2", "1", "3", "3")
.map(Integer::parseInt)
// 第一个值是默认值
// 之后每次都会将上一次的操作结果赋值给x y 就是每次从数据中获取的元素。
.reduce(0, (a, b) -> {
return a + b;
});
System.out.println(reduce);
12、 map和reduce的组合
13、 mapToint方法
Integer占用的内存比int多很多,在stream流操作中会自动装箱和拆箱操作。
为了提高程序代码的效率,我们可以将流中Integer数据转换为int数据,然后再操作。
IntStream intStream = Stream.of("2", "1", "3", "3")
.map(Integer::parseInt)
.mapToInt(Integer::intValue);
intStream.filter(s -> s > 2)
.forEach(System.out::println);
14、 find方法
如果我们需要找到某些数据,可以使用find方法来实现
OptionalfindFirst(); //获取到第一个元素 optional findAny(); //随机的获取到一个元素
Optional15、 concat方法b = Stream.of("1", "2", "3", "3").findAny();
将两个流合并到一起
Stream三、案例stringStream = Stream.of("2", "1", "3", "3"); Stream integerStream = Stream.of(4, 5, 6, 7); Stream.concat(stringStream, integerStream) .filter(s->{ return s instanceof String; }).forEach(System.out::println);
定义两个集合,然后在集合汇总存储多个用户名称,然后完成如下的操作。
1、第一个队伍只保留姓名长度为3的成员
2、第一个队伍筛选之后只要前三人
3、第二个队伍只要性张的成员
4、第二个队伍筛选之后不要前两个人
5、将两个队伍合并为一个队伍
6、根据姓名创建Person对象
7、打印整个队伍的Person信息
// 收集到list集合中 Listcollect = Stream.of("a", "b", "c") .collect(Collectors.toList());
// 收集到set集合中 Setcollect = Stream.of("a", "b", "c") .collect(Collectors.toSet());
// 返回具体的实例 ArrayListcollect = Stream.of("a", "b", "c") .collect(Collectors.toCollection(() -> new ArrayList<>()));
// 返回数组
Object[] collect = Stream.of("a", "b", "c")
.toArray();
String[] strings = Stream.of("a", "b", "c")
.toArray(String[]::new);
五、聚合计算
六、分组操作
Stream七、对流中的数据做分区操作stream = Stream.of(new Person("小明", 20), new Person("小花", 21), new Person("小兰", 20)); Map > collect = stream .collect(Collectors.groupingBy(Person::getAge)); collect.forEach((key,value)->{ System.out.println(key + " " + value.size()); });
Stream八、并行流stream = Stream.of(new Person("小明", 20), new Person("小花", 21), new Person("小兰", 20)); Map > collect = stream.collect(Collectors.partitioningBy(s -> s.getAge() > 20));
前面的Stream流都是串行流,也就是在一个线程上面执行。
parallelStream其实就是一个并行执行的流,他通过默认的ForkJoinPool
// stream的形式转换 Streamparallel1 = Stream.of(1, 2, 3).parallel();
// list的形式转换 Stream串行流和并行流的对比integerStream = Arrays.asList(1, 2, 3).parallelStream();
并行流的效率是很高的,并行处理的过程会分而治之,也就是将一个大的任务分成了多个小的任务。每个任务都是一个线程操作。
并行流下的数据安全问题:
比如Arraylist不是线程安全的,这种的使用并行流就可能出现问题
问题的解决:
1、加锁
2、使用线程安全的容器vector



