目录
一、count方法(统计)
统计是一个 最终操作,返回Stream中元素的个数,返回值类型是 long。
//数组转流
String[] array = {"暧昧","意外","像风一样","绅士"};
Stream<String> arrayStream = Arrays.stream(array);
long count = arrayStream
.filter((music)->{//过滤
return music.length() == 2;
})
.count();//统计
System.out.println(count);
filter方法过滤出长度为2的内容,count方法进行统计,输出结果为3。
二、match方法(匹配)
Stream提供了多种匹配操作,允许检测指定的Predicate是否匹配整个Stream。所有的匹配操作都是 最终操作 ,并返回一个 boolean 类型的值。
List<String> list = Arrays.asList("暧昧","意外","像风一样","绅士");
//是否所有的内容长度都为4
boolean is1 = list.stream()
.allMatch((music)->{
return music.length() == 4;
});
//是否存在一个内容长度为4的
boolean is2 = list.stream()
.anyMatch((music)->{
return music.length() == 4;
});
//没有一个内容长度为4的歌
boolean is3 = list.stream()
.noneMatch((music)->{
return music.length() == 1;
});
System.out.println(is1);
System.out.println(is2);
System.out.println(is3);
all判断全部内容,any判断是否含有,none判断全部内容是否都不满足条配件。
三、max()和min()方法
取流中的最大值和最小值,比较规则可自定义
示例:获取歌曲名称最长的歌曲名
提供的集合:
List<String> list = Arrays.asList("暧昧","意外","像风一样","绅士","你还要我怎样","我知道你都知道");
方法1:不使用max()方法:
String musicName = list.stream()
.sorted((x,y)->{//排序
if(x.length() == y.length()){
return x.compareTo(y);
}
return y.length() - x.length();
})
.findFirst().get();//获取流中的元素
System.out.println(musicName);
则需要先对流中数据进行排序,然后调用findFirst()方法的get()方法才能获取
方法2:使用max()方法
String musicName2 = list.stream().max((x,y)->{
return x.length() - y.length();
}).get();
System.out.println(musicName2);
方法中接口实现均使用lambda表达式,不懂可以看上一篇博客。
四、collect()收集方法
1、收集成单列集合
String[] array = {"暧昧","意外","像风一样","绅士","绅士","暧昧","意外","你还要我怎样","我知道你都知道"};
//collect收集成list集合默认为ArrayList(元素有序不唯一)
List<String> list = Arrays.stream(array)
.distinct()
.collect(Collectors.toList());
System.out.println(list);
//collect收集成set集合默认为HashSet(元素无序且唯一)
Set<String> set = Arrays.stream(array)
.collect(Collectors.toSet());
System.out.println(set);
//LinkedList::new lambda表达式的一种,代表对象的创建
//collect收集成list集合默认为LinkedList(有序不唯一)
LinkedList<String> LinkedList = Arrays.stream(array)
.distinct()
.collect(Collectors.toCollection(LinkedList::new));
System.out.println(LinkedList);
//collect收集成LinkedHashSet集合(元素有序且唯一)
LinkedHashSet<String> LinkedHashSet = Arrays.stream(array)
.collect(Collectors.toCollection(LinkedHashSet::new));
System.out.println(LinkedHashSet);
可使用默认提供的集合收集,也可使用自己需要的,使用lambda表达式LinkedList::new传入一心想要使用的收集集合。
2、收集成map集合
///collect收集成Lmap集合
Map<String,Integer> map1 = Arrays.stream(array).distinct()
.collect(
Collectors.toMap((music)->{return music;},
(music)->{return music.length();}));
System.out.println(map1);
//方法体中只有一行操作,可省略大括号
Map<String,Integer> map2 = Arrays.stream(array).distinct()
.collect(
Collectors.toMap(music->music,
music->music.length()));
System.out.println(map2);
}
需要使用收集工具类Collectors的toMap方法收集。
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
在调用toMap方法时需要实现Function对键和值进行处理,且默认提供HashMap集合进行收集。
3、在收集的同时可进行额外操作
(1)映射处理
将字符串数组收集成Ingeter类型的数组存储。
List<String> strlist = Arrays.asList("12","23","34","45","56");
List<Integer> numlist = strlist.stream()//转换 成流
.collect(Collectors.mapping(//收集的同时,进行处理映射
s->Integer.parseInt(s)*10,//字符类型转换为Integer类型
Collectors.toList()//收集成Integer数组
));
System.out.println(strlist);
System.out.println(numlist);
结果显示:
(2)分组处理
使用收集工具类Collectors的groupingBy方法
List<String> list = Arrays.asList("曹操","张飞","刘备","曹丕","张辽","曹植","张郃","刘禅","曹冲","曹仁","张宁","司马懿");
//按姓氏分组
Map<Character,List<String>> resultMap = list.stream()
.collect(Collectors.groupingBy(name->name.charAt(0)));
System.out.println(resultMap);
结果显示:这里是以名字中第一个字分的,暂时不考虑复姓
(3)分区处理
//按照名字长度是否为2分区
Map<Boolean,List<String>> resultPartingMap = list.stream()
.collect(Collectors.partitioningBy(name->name.length()==2));
System.out.println(resultPartingMap);
使用收集工具类Collectors的partitioningBy方法,返回的map集合键为布尔,以是否满足条件分。
public static <T>
Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) {
return partitioningBy(predicate, toList());
}
结果显示:
五、Statistics 统计
统计是一个最终操作,返回Stream中元素的各类统计信息,返回值类型是 XXXConsumer。
List<Integer> number = Arrays.asList(1,2,3,4,5);
IntSummaryStatistics statistics = number.stream().mapToInt(x->x).summaryStatistics();
System.out.println("最大值" + statistics.getMax());//数据中最大值
System.out.println("最小值" + statistics.getMin());//数据中最小值
System.out.println("平均值" + statistics.getAverage());//数据平均值
System.out.println("累加和" + statistics.getSum());//数据的累加和
System.out.println("总个数" + statistics.getCount());//数据的总个数
结果显示:
Statistics 统计使用时需要将数据转换为数值类型,int,doubl才可以操作。
六、Parallel Streams 并行流
Stream有串行和并行两种,串行Stream上的操作是在一个线程中依次完成,而并行Stream则是在多个线程上同时执行。
示例:排序
准备示例数据:
int max = 1000000;
List<String> values = new ArrayList<>(max);
for(int i = 0 ;i < max ;i++){
UUID uuid = UUID.randomUUID();
values.add(uuid.toString());
}
串行排序:
long start = System.currentTimeMillis();
//串行流(普通流)
long count = values.stream().sorted().count();
long end = System.currentTimeMillis();
System.out.println(end - start);
串行排序,耗时共计930毫秒
并行排序:
long start = System.currentTimeMillis();
//并行流
long count = values.stream().sorted().count();
long end = System.currentTimeMillis();
System.out.println(end - start);
并行排序,耗时共计774毫秒
运行结果可能有差异,与电脑性能有关,但对比不难发现,并行效率更高,速度更快。
函数式接口小总结:
- 1 Predicate、Function、Consumer、Comparator
- 2 通过链式编程,使得它可以方便地对数据进行链式处理。
- 3 方法参数都是函数式接口类型。
- 4 一个 Stream 只能操作一次,操作完就关闭了,继续使用这个 Stream 会报错。
- 5 Stream 不保存数据,不改变数据源。