Java8新特性之Stream


Stream是什么?

Stream API (java.util.stream)把真正的函数式编程风格引入到Java中,这是目前为止对Java类库最好的补充,因为Stream API可以极大提供Java程序员的生产力,让程序员写出高效、干净、简洁的代码、
Stream是Java8中处理集合的关键抽象概念,它可以指定你对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API对集合数据进行操作,就类似于使用SQL执行的数据库查询。也可以使用Stream API来执行操作。简言之,Stream API提供了一种高效且易于使用的处理数据的方式。

是数据渠道,用于操作数据源(集合,数组等)所生成的元素序列。
“集合讲的是数据,Stream讲的是计算!”

注意

  1. Stream自己不会存储元素。
  2. Stream不会改变该源对象,相反,他们会返回一个持有结果的新Stream。
  3. Stream操作是延迟执行的,这意味着他们会等到需要结果的时候才执行。

如何操作Stream

三个步骤:

  1. 创建Stream (四种方法) 常用前两个
import ming.lambda.Cat;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 1. Stream 关注的是对数据的运算,与CPU打交道
 *   集合关注的是数据存储,与内存打交道
 *
 * 2. Stream 自己不会存储元素,
 *    Stream 不会改变源对象,相反他们会返回一个持有结果的新Stream
 *    Stream 操作是延迟执行的,(因为在终止操作才执行)
 *
 * 3. 流程
 *   Stream实例化 --> 一系列中间操作 -->  终止操作
 *
 */
public class StreamDemo1 {
//    Stream实例化 
    
//    一、通过集合
    @Test
    public void test1(){
        //1. 利用List的stream() : 返回一个顺序流
        List<Cat> catList = CatData.getCatList();
        Stream<Cat> stream = catList.stream();

        //2. List中的parallelStream() : 返回一个并行流
        Stream<Cat> stream1 = catList.parallelStream();
    }

//   二、 通过数组
    @Test
    public void test2(){
        //1. 利用Arrays类的static Stream<T> stream(T[] array): 返回一个流
        int[] arr=new int[]{1,2,3,4,5,6};
        IntStream stream = Arrays.stream(arr);
        
        Cat cat1 = new Cat();
        Cat cat2 = new Cat();
        Cat[] cats = new Cat[]{cat1,cat2};
        Stream<Cat> stream1 = Arrays.stream(cats);
    }

//    三、Stream的of()
    @Test
    public void test3(){
        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
    }

//    四、创建无限流  (用于造数据)
    @Test
    public void test4(){
        //迭代 public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f){}
        //遍历前10个偶数
        Stream.iterate(0,t->t+2).limit(10).forEach(System.out::println);

        //生成 public static<T> Stream<T> generate(Supplier<T> s){}
        //遍历生成前10个随机数
        Stream.generate(Math::random).limit(10).forEach(System.out::println);
    }
}
  1. 中间操作
    三种类型
    (1)筛选与切片
    (2)映射
    (3)排序
    前期准备
import ming.lambda.Cat;      //自己定义Cat实体类
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: mei_ming
 * @DateTime: 2022/6/3 16:30
 * @Description: 测试数据源
 */
public class CatData {
    public static List<Cat> getCatList(){
        List<Cat> cats = new ArrayList<>();
        cats.add(new Cat( "cat1",  1,  "bule",  1400));
        cats.add(new Cat( "cat2",  2,  "red",  1500));
        cats.add(new Cat( "cat3",  3,  "yellow",  4000));
        cats.add(new Cat( "cat4",  4,  "bule",  2000));
        cats.add(new Cat( "cat5",  1,  "bule",  2500));
        cats.add(new Cat( "cat6",  2,  "bule",  1600));
        cats.add(new Cat( "cat10",  3,  "orange",  2100));
        cats.add(new Cat( "cat11",  4,  "bule",  1900));
        return cats;
    }
}

import ming.lambda.Cat;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * @Author: mei_ming
 * @DateTime: 2022/6/3 16:54
 * @Description: Stream的中间操作
 */
public class StreamDemo2 {
//    Stream的中间操作
    //1.筛选与切片
    @Test
    public void test1(){
        List<Cat> list = CatData.getCatList();
        //filter :  Stream<T> filter(Predicate<? super T> predicate) --接收lambda,从流中排除某些元素
        //查找小猫价格大于2000的猫
        Stream<Cat> stream = list.stream();
        stream.filter(cat -> cat.getPrice()>2000).forEach(System.out::println);

        System.out.println();
        //limit(n)  -截断流,使其元素不超过给定的数量
        list.stream().limit(3).forEach(System.out::println);

        System.out.println();
        //skip(n) -跳过元素
        list.stream().skip(3).forEach(System.out::println);

        System.out.println();
        //distinct --筛选
        list.add(new Cat("cat9",1,"bule",2000));
        list.add(new Cat("cat9",1,"bule",2000));
        list.add(new Cat("cat9",1,"bule",2000));
        list.add(new Cat("cat9",1,"bule",2000));
//        System.out.println(list); //出现重复元素
//        list.stream().distinct().forEach(System.out::println);   //需要重写hashcode与equals
    }

    //2.映射
    @Test
    public void test2(){
        //1.  <R> Stream<R> map(Function<? super T, ? extends R> mapper);  映射   相当于add()
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
        list.stream().map(str->str.toUpperCase()).forEach(System.out::println);

        System.out.println();
        //获取Cat name名字长度大于4的Cat名字
        List<Cat> list1 = CatData.getCatList();
        Stream<String> nameStream = list1.stream().map(Cat::getName);
        nameStream.filter(name->name.length()>4).forEach(System.out::println);   //cat10,cat11
        System.out.println();

        //练习2: 遍历每个元素
        Stream<Stream<Character>> streamStream = list.stream().map(StreamDemo2::fromStringTOStream);
        streamStream.forEach(s->{
            s.forEach(System.out::println);
        });
        System.out.println();

        //2.  <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);  相当于addAll()
        //利用flatMap 简化 练习2 遍历每个元素
        list.stream().flatMap(StreamDemo2::fromStringTOStream).forEach(System.out::println);
    }

    //将字符串中的多个字符构成的集合转换成对应的Stream的实例
    public static Stream<Character> fromStringTOStream(String str){
        ArrayList<Character> list = new ArrayList<>();
        for (Character c:str.toCharArray()) {
            list.add(c);
        }
        return list.stream();
    }

    @Test
    public void test3(){
        ArrayList list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        ArrayList list1 = new ArrayList();
        list1.add(4);
        list1.add(5);
        list1.add(6);
//        list.add(list1);  // [1, 2, 3, [4, 5, 6]]
        list.addAll(list1);  // [1, 2, 3, 4, 5, 6]
        System.out.println(list);
    }

//    3.排序
    @Test
    public void test4(){
       //1.sorted() --自然排序
        List<Integer> list = Arrays.asList(12, 59, 0, -20, 10, 30);
        list.stream().sorted().forEach(System.out::println);

        //抛出异常 ClassCastException: ming.lambda.Cat cannot be cast to java.lang.Comparable
//        List<Cat> list1 = CatData.getCatList();
//        list1.stream().sorted().forEach(System.out::println);
        System.out.println();
        //2. sorted(Comparator com)  --定制排序
        List<Cat> list1 = CatData.getCatList();
        list1.stream().sorted((cat1,cat2)->{
            return Integer.compare(cat1.getAge(),cat2.getAge());
        }).forEach(System.out::println);

    }
}
  1. 终止操作
    三种类型
    (1)匹配与查找
    (2)规约
    (3)收集
import ming.lambda.Cat;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: mei_ming
 * @DateTime: 2022/6/3 17:50
 * @Description: Stream的终止操作
 *
 */
public class StreamDemo3 {
    //1. 匹配与查找
    @Test
    public void test1(){
        List<Cat> catList = CatData.getCatList();
        //allMatch() :boolean allMatch(Predicate<? super T> predicate);
        //是否所有的Cat的价格都大于2000
        boolean allMatch = catList.stream().allMatch(cat -> cat.getPrice() > 2000);
        System.out.println(allMatch);  //false
        System.out.println();

        //anyMatch() :boolean anyMatch(Predicate<? super T> predicate);
        //是否存在的Cat的价格大于2000
        boolean anyMatch = catList.stream().anyMatch(cat -> cat.getPrice() > 2000);
        System.out.println(anyMatch); //true
        System.out.println();

        //noneMatch() :boolean noneMatch(Predicate<? super T> predicate);  检查是否没有匹配的元素
        //是否没有Cat的价格大于5000
        boolean noneMatch = catList.stream().noneMatch(cat -> cat.getPrice() > 5000);
        System.out.println(noneMatch);  //true
        System.out.println();

        //findFirst() :Optional<T> findFirst();
        //返回第一个元素
        Optional<Cat> first = catList.stream().findFirst();
        System.out.println(first);
        System.out.println();

        //findAny() :Optional<T> findAny();
        //返回第一个元素
        Optional<Cat> any = catList.stream().findAny();
        System.out.println(first);
        System.out.println();

        //count() :long count();
        //返回大于2000的个数
        long count = catList.stream().filter(cat -> cat.getPrice() > 2000).count();
        System.out.println(count);
        System.out.println();

        //max() :Optional<T> max(Comparator<? super T> comparator);
        //返回最高价格
        Stream<Double> priceStream = catList.stream().map(cat -> cat.getPrice());
        Optional<Double> max = priceStream.max((cat1price, cat2price) -> Double.compare(cat1price,cat2price));
        System.out.println(max);
        System.out.println();

        //min() :Optional<T> min(Comparator<? super T> comparator);
        //返回最低价格的Cat
        Optional<Cat> min = catList.stream().min((cat1, cat2) -> Double.compare(cat1.getPrice(), cat2.getPrice()));
        System.out.println(min);
        System.out.println();

        //forEach() : 遍历
        catList.stream().forEach(System.out::println);
    }

    //2. 规约
    @Test
    public void test2(){

        //reduce() :T reduce(T identity, BinaryOperator<T> accumulator);
        //计算1到10的和
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer sum = list.stream().reduce(0, Integer::sum);
        System.out.println(sum);
        System.out.println();

        //reduce() :Optional<T> reduce(BinaryOperator<T> accumulator);
        //计算Cat的价格总和
        List<Cat> catList = CatData.getCatList();
        Stream<Double> priceStream = catList.stream().map(cat -> cat.getPrice());
        Optional<Double> priceSum = priceStream.reduce(Double::sum);
        System.out.println(priceSum);
        System.out.println();

    }

    //3. 搜集
    @Test
    public void test3(){
        //collect() :将流转换成其他形式
        //查找价格大于2000的Cat 并放入Set/List
        List<Cat> catList = CatData.getCatList();
        Stream<Cat> catStream = catList.stream().filter(cat -> cat.getPrice() > 2000);
        List<Cat> list = catStream.collect(Collectors.toList());  //toSet()/toCollection()
        list.forEach(System.out::println);
        System.out.println();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值