Stream流(2)

聚合操作

将流中的数据进行汇聚为一个值,一般都是终止操作min和max用于获取最小值和最大值,注意Comparator接口,count用于统计元素个数

List<Integer> list = new ArrayList<>(); 
list.add(10); 
list.add(39); 
list.add(10); 
list.add(78); 
list.add(39); 
Integer maxValue = list.stream().max(Integer::compareTo).get(); 
System.out.println(maxValue); 
long len=list.stream().count(); 
System.out.println(len);

利用收集器Collectors实现的聚合操作 

List<Integer> list = new ArrayList<>(); 
list.add(10); 
list.add(39); 
list.add(10); 
list.add(78); 
list.add(39); 
//总和、平均值、最大值、最小值 
// 针对int类型的数据进行累加操作,会使用参数lambda表达式将元素转换为int类型 
long sum = list.stream().collect(Collectors.summarizingInt(Integer::intValue)).getSum();
System.out.println(sum); 
// 求平均值 
Double avg = list.stream().collect(Collectors.averagingInt(Integer::intValue)); 
System.out.println(avg); 
//求最大值 最小值
Integer maxValue=list.stream().collect(Collectors.maxBy(Integer::compare)).get(); 
Integer min=list.stream().collect(Collectors.minBy(Integer::compareTo)).get(); 
System.out.println("max:"+maxValue+",min:"+min);

Collectors类实现了很多的聚合操作,例如将流转换为集合或者聚合元素,Collector可以返回列表List或者字符串

List<String> list1=Arrays.asList("abc","","bcd","","efg","abcd","jklm"); 
List<String> list2=list1.stream().filter(str->!str.isEmpty())//剔除空字符串 
    .collect(Collectors.toList()); 
String result = list1.stream().filter(str -> !str.isEmpty())     
    .collect(Collectors.joining(","));

查找元素

findFirst返回非空集合中的第一个元素值,一般会与filter方法结合使用

List<Integer> list = new ArrayList<>(); 
list.add(10); 
list.add(39); 
list.add(10); 
list.add(78); 
list.add(39); 
Optional<Integer> op = list.stream().filter(i -> i > 20).findFirst(); 
    if(op.isPresent()) 
        System.out.println(op.get()); 
    else
        System.out.println("没有数据");

findAny可以在stream中找到任意一个所匹配的元素就直接返回,在流的平行处理十分有效

List<Integer> list = new ArrayList<>(); 
list.add(10); 
list.add(39); 
list.add(10); 
list.add(78); 
list.add(39); 
Integer any=list.parallelStream().filter(i->i>20).findAny().get();

anyMathch判定是否还有匹配的元素,返回一个boolean值

List<Integer> list = new ArrayList<>(); 
list.add(10); 
list.add(39); 
list.add(10); 
list.add(78); 
list.add(39); 
boolean res=list.parallelStream().anyMatch(i->i>100);

类似的方法allMatch和noneMatch分别是判断所有元素都满足条件或者没有元素满足条件返回true,否则false。这些方法都是用来检查整个流,所以可以通过使用并行流提高速度。


reduce归并

reduce方法用于将流种的元素进行进一步的对并计算

List<Integer> nums = Arrays.asList(13, 2, 2, 3, 7, 3, 5); 
// 求和 
Integer sum = nums.stream().reduce((x, y) -> x + y).get(); 
System.out.println(sum); 
// 简化写法
Integer sum1 = nums.stream().reduce(Integer::sum).get(); 
System.out.println(sum1); 
// 可以指定初始值的求和计算,参数1就是累加器的初始值 
Integer sum2 = nums.stream().reduce(10, Integer::sum); 
System.out.println(sum2); 
// 对元素的长度进行求和 
int sum3 = nums.stream().map(Object::toString).mapToInt(String::length).sum(); 
System.out.println(sum3); 
// 复杂的写法 
int sum4 = nums.stream().reduce(0, (total, y) -> total + y.toString().length(), (t1, t2) -> t1 + t2); 
System.out.println(sum4);

收集结果

当数据经过souce--transform--sink处理后进行处理结果的收集。一般使用Collectors提供的常见的收集器

集合

//将处理结果存储到一个List中 
Random r = new Random(); 
List<Integer> intList = r.ints().limit(10).mapToObj(Integer::valueOf).collect(Collectors.toList()); 
System.out.println(intList); 
//将处理结果存储到一个Set中 
Set<Integer> intSet = r.ints().limit(10).mapToObj(Integer::valueOf).collect(Collectors.toSet()); 
System.out.println(intSet);

字符串 

 将stream中的字符串连接并收集起来,可以在元素之间添加指定符号

Random r = new Random(); 
//将字符串类型的stream使用特定符号进行拼接,拼接为一个字符串 
String res=r.ints().limit(10).mapToObj((x)- >""+x).collect(Collectors.joining(","));

Map集合

可以使用Collectors.toMap方法将集合中的元素收集到Map中,但是要求有2个参数,分别用来生成 Map中的key值和value值。

List<Person> list = new ArrayList<>(); 
Random r = new Random(); 
    for (int i = 0; i < 10; i++) { 
        Person p = new Person(); 
        p.setId(i + 1L); 
        p.setName("name-" + i); 
        p.setAge(r.nextInt(8) + 14);
        list.add(p); 
    } 
//以对象的id值作为key,存储的value为name属性值 
Map<Long, String> map1 = list.stream().collect(Collectors.toMap(Person::getId, Person::getName)); 
System.out.println(map1); 
// Function.identity()用于获取实际的对象 
Map<Long, Person> map2 = list.stream().collect(Collectors.toMap(Person::getId, Function.identity())); 
System.out.println(map2);

分组操作

按照年龄分组操作

List<Person> list = new ArrayList<>(); 
Random r = new Random(); 
    for (int i = 0; i < 10; i++) { 
        Person p = new Person(); 
        p.setId(i + 1L); 
        p.setName("name-" + i); 
        p.setAge(r.nextInt(8) + 14); 
        list.add(p); 
    } 
Map<Integer, List<Person>> map1 = list.stream().collect(Collectors.groupingBy(Person::getAge)); 
System.out.println(map1);

 当分组条件是一个返回boolean值的函数时,流元素可以分为2组列表,一个是返回true的元素集合,一个是返回false的元素集合

List<Person> list = new ArrayList<>(); 
Random r = new Random(); 
    for (int i = 0; i < 10; i++) { 
        Person p = new Person(); 
        p.setId(i + 1L); 
        p.setName("name-" + i); 
        p.setAge(r.nextInt(8) + 14); 
        list.add(p); 
    }
//将大于20岁的人分为一组,将不大于20岁的人分为一组 
Map<Boolean, List<Person>> map1 = list.stream().collect(Collectors.partitioningBy(p -> p.getAge() > 20)); 
System.out.println(map1);

并行流中的问题

stream使并行计算比较容易,在数据量较大的集合中可以体现出并行流的优势,利用多核CPU资源提升执行效率。但是使用需要注意一些问题。

首先必须是并行流。parallel方法可以将任意的串行流转换为并行流

Stream.of(1, 2, 3, 5, 6, 7).forEach(System.out::println); 
System.out.println(); 
//将一个串行流转换为并行流 
Stream.of(1, 2, 3, 5, 6, 7).parallel().forEach(System.out::println);

 其次要确保传递给并行流的操作函数是线程安全的

int[] bb = new int[10]; 
Stream.of(1, 2, 2, 5, 2, 7).parallel().forEach(s -> { 
    if (s < 5)
        bb[s]++; 
    }); 
System.out.println(Arrays.toString(bb));

转换结构

转换为数组

Object[] arr = Stream.of(1, 2, 2, 5, 2, 7).toArray(); 
System.out.println(Arrays.toString(arr)); 
Integer[] arr2 = Stream.of(1, 2, 2, 5, 2, 7).toArray(Integer[]::new); 
System.out.println(Arrays.toString(arr));

转换为集合

List<Integer> list = Stream.of(1, 2, 2, 5, 2, 7).collect(Collectors.toList()); 
System.out.println(list); 
ArrayList<Integer> list2 = Stream.of(1, 2, 3, 4, 5).collect(Collectors.toCollection(ArrayList::new)); 
System.out.println(list2); 
Set<Integer> set1 = Stream.of(1, 2, 2, 4, 2, 5).collect(Collectors.toSet()); 
System.out.println(set1); 
Stack<Integer> stack = Stream.of(1, 2, 2, 4, 2, 5).collect(Collectors.toCollection(Stack::new)); 
System.out.println(stack);

转化为string

String res = Stream.of("1", "2", "2", "5", "2", "7")
    .collect(Collectors.joining()); 
System.out.println(res);

总结:

stream不是数据结构,没有内存内部存储,只是用操作管道从source中抓取数据,不修改数据的 底层结构;

一般stream的操作都是使用lambda表达式为参数;

不支持索引访问;

stream具有惰性化特征,很多的stream都是向后延迟,直到搞清楚有多少数据后进行计算;

并行化操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值