zoukankan      html  css  js  c++  java
  • Java 8中Stream API

    Stream简介

    1. Java 8引入了全新的Stream API。这里的Stream和I/O流不同,它更像具有Iterable的集合类,但行为和集合类又有所不同。
    2. stream是对集合对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作,或者大批量数据操作。
    3. 只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

    为什么要使用Stream

    1. 函数式编程带来的好处尤为明显。这种代码更多地表达了业务逻辑的意图,而不是它的实现机制。易读的代码也易于维护、更可靠、更不容易出错。
    2. 高端
    实例数据源
    public class Data {
    private static List<PersonModel> list = null;
    static {
    PersonModel wu = new PersonModel("wu qi",18, "男");
    PersonModel zhang = new PersonModel(" zhang san" , 19, "男");
    PersonModel wang = new PersonModel( "wang si", 20, "女");
    PersonModel zhao = new PersonModel(" zhao wu", 20,“男");
    PersonModel chen = new PersonModel("chen liu" ,21, "男");
    list = Arrays.asList(wu, zhang, wang, zhao, chen);
    public static List<PersonModel> getData() {
    return list;
    }
    
    Filter
    1. 遍历数据并检查其中的元素时使用。
    2. filter接受一个函数作为参数,该函数用Lambda表达式表示。
    过滤所有的男性
    public static void fiterSex(){
    List<PersonModel> data = Data . getData();
    //old
    List<PersonModel> temp=new ArrayList<>();
    for (PersonModel person:data) {
    if ("男".equals(person.getSex))){
    temp. add(person);
    }
    System. out. println(temp);
    //new
    List<PersonModel> collect = data
    .stream() 
    .filter(person ->“男". equals(person. getSex()))
    .collect(toList());
    System. out. println(collect);
    }
    /**
    过滤所有的男性并且小于20岁
    **/
    public static void fiterSexAndAge(){
    List<PersonModel> data - Data. getData();
    //old
    List<PersonModel> temp=new ArrayList<>();
    for (PersonModel person:data) {
    if ("男".equals(person.getSex() )&&person.getAge()<20){
    temp . add(person);
    }
    //new 1
    List<PersonModel> collect = data
    .stream()
    .filter(person -> {
    if ("男" .equals(person. getSex()8&person. getAge()<28){
    return true;
    }
    return false;
    })
    .collect(toList());
    //new
    List<PersonModel> collect1 = data
    . stream()
    .filter(person -> (“男" .equals(person.getSex()&person. getAge()<20))
    .collect(toList());
    }
    
    
    
    Map
    1. map生成的是个一对一映射,for的作用
    2. 比较常用
    3. 而且很简单
    /**取出所有的用户名字**/
    public static void getUserNameList(){
    List<PersonMdel> data = Data. getData();
    //old
    List<String> list=new ArrayList<>(); 
    for (PersonModel pers ion :data) {
    list. add(persion. getName());
    System. . out .println(list);
    //new 1
    List<String> collect = data.stream() . map(person -> person .getName()).collect(toList());
    System. out . printIn(collect);
    //new 2
    List<String> collect1 = data.stream().map(PersonModel::getName).collect(toList()); 
    System.out.printIn(collect1);
    //new 3
    List<string> collect2 = data . stream() .map(person -> {
    System. out . printIn(person . getName());
    return person. getName();
    }).collect(toList());
    
    
    FlatMap
    1. 顾名思义,跟map差不多,更深层次的操作

    2. 但还是有区别的

    3. map和flat返回值不同

    4. Map 每个输入元素,都按照规则转换成为另外一个元素。
      还有一些场景,是一对多映射关系的,这时需要 flatMap。

    5. Map一对一

    6. Flatmap一对多

    7. map和flatMap的方法声明是不一样的

    8. (1) Stream map(Function mapper);

    (2) Stream flatMap(Function> mapper);

    (3) map和flatMap的区别:我个人认为,flatMap的可以处理更深层次的数据,入参为多个list,结果可以返回为一个list,而map是一对一的,入参是多个list,结果返回必须是多个list。通俗的说,如果入参都是对象,那么flatMap可以操作对象里面的对象,而map只能操作第一层。

    public static void flatMapString() {
    List<PersonModel> data = Data . getData();
    //返回类型不一样
    List<String> collect - data.stream()
    .flatMap(person -> Arrays . stream(person. getName().split(" "))).collect(toList()); 
    List<Stream<String>> collect1 = data.stream()
    .map(person -> Arrays . stream(person. getName().split(" "))).collect(toList());
    //用map实现
    List<String> collect2 - data. stream()
    .map(person -> person. getName().split(" "))
    .flatMap (Arrays: :stream) . collect(toList()); 
    //另- 种方式
    List<string> collect3 = data. stream()
    .map(person -> person. getName().split(" "))
    .flatMap(str -> Arrays.asList(str). stream()).collect(toList());
    }
    
    
    Reduce
    1. 感觉类似递归
    2. 数字(字符串)累加
    public static void reduceTest(){
    //累加,初始化值是10
    Integer reduce = Stream.of(1, 2, 3, 4)
    .reduce(10, (count, item) ->{
    System . out . println(”count:"+count);
    System . out . println(”item:" +item);
    return count + item ;
    } );
    System. out . println(reduce);
    Integer reduce1 = Stream.of(1, 2, 3, 4)
    .reduce(0, (x, y) -> x + y);
    System. out . println(reduce1);
    String reduce2 = Stream.of ("1", "2", "3")
    .reduce("e", (x, y) -> (x +",”+ y));
    System. . out .println(reduce2);
    }
    
    
    
    Collect
    1. collect在流中生成列表,map,等常用的数据结构
    2. toList()
    3. toSet()
    4. toMap()
    5. 自定义
    tolist
    public static void tolistTest(){
    List<PersonModel> data = Data. getData(); 
    List<String> collect = data. stream()
    .map(PersonModel: getName)
    .collect(Collectors.toList());
    }
    /*
    toSet
    */
    public static void toSetTest(){
    List<PersonModel> data = Data .getData();
    Set<String> collect = data. stream()
    . map(PersonModel: getName )
    . collect(Collectors . toSet());
    }
    toMap
    public static void toMapTest(){
    List<PersonModel> data - Data . getData();
    Map<String. Integery collect = data .stream()
    .collect(
    Collectors. toMap(PersonModel : :getName, PersonModel: getAge)
    );
    data. stream()
    .collect(Collectors. toMap(per->per . getName(), value->{
    return value+"1";
    }));
    }
    /*
    指定类型
    **/
    public static void toTreeSetTest(){
    List<PersonModel> data = Data . getData();
    TreeSet<PersonModel> collect = data.stream()
    .collect (Collectors. toCollection(TreeSet: :new));
    System. out . printIn(collect);
    }
    //分组
    public static void toGroupTest(){
    List<PersonModel> data = Data. getData();
    Map<Boolean, ListcPersonModel>> collect = data. stream()
    .col lect(Collectors.groupingBy(per ->“男" . equals(per . get<e)x))));
    System. out . println(collect);
    }
    //分隔
    public static void toJoiningTest(){
    List<PersonModel> data = Data . getData();
    String collect = data.stream()
    .map(personModel -> personModel . getName())
    .collect(Collectors .joining(",", "{", "}")); 
    System.out.println(collect);
    /* *
    *自定义
    */
    public static void reduce(){
    List<String> collect - Stream.of("1", "2", "3").col1ect(
    Collectors .reduc ing(new ArrayList<String>(), x -> Arrays.asList(x), (y, z) -> {
    y . addAll(z); 
    return y;
    }));
    System. out. println(collect);
    
    
    
    Optional
    1. Optional 是为核心类库新设计的一个数据类型,用来替换 null 值。
    2. 人们对原有的 null 值有很多抱怨,甚至连发明这一概念的Tony Hoare也是如此,他曾说这是自己的一个“价值连城的错误”
    3. 用处很广,不光在lambda中,哪都能用
    4. Optional.of(T),T为非空,否则初始化报错
    5. Optional.ofNullable(T),T为任意,可以为空
    6. isPresent(),相当于 !=null
    7. ifPresent(T), T可以是一段lambda表达式 ,或者其他代码,非空则执行
    public static void main(String[] args) {
    PersonModel personMode l=new PersonModel();
    //对象为空则打出
    Optional<object>。= Opt ional . of (personModel);
    System. . out .println(o.ispresent()?o.get():"-"); 
    //名称为空则打出一
    optional<String> name = optional . ofNullable(personModel . getName());
    System.out .print In(name . isPresent()?name.get():"-");
    //如果不为空,则打出xxx
    Optional .ofNullable("test" ).ifPresent(na->{
    System . out . println(na+" ifPresent );
    });
    //如果空, 则返回指定字符串
    System.out. println(Optional.ofNullable(nul1).orElse("-")); 
    System . out . println(Optional .ofNullable("1" ).orElse("-"));
    //如果空, 则返回指定方法, 或者代码
    System .out . print ln(Optional .ofNullable(nul1) .orElseGet(()->{
    return "hahah";
    }));
    System. . out .println(Opt ional.ofNullable("1" ).orElseGet(()->{ 
    return "hahah";
    }));
    //如果空,则可以抛出异常
    System.out.println(Optional.ofNullable("1" ) .orElseThrow(()->{
    throw new RuntimeException("ss");
    })):
    
        
    objects . requireNonNull(null,"is nul1");
    //利用Optional进行多级判断
    EarthModel earthModel1 = new EarthModel(); 
    //old
    if (earthModel!=null){
    if (earthModel1.getTea()!=nul1){
    11...
    }
    }
    / /new
    Opt ional .ofNullable(earthModel1)
    .map(EarthModel::getTea)
    .map(TeaModel::getType)
    .isPresent();
    //
    Optional<EarthModel> earthModel = Optional.ofNullable(new EarthModel());
    Optional<List<PersonModel>> personModels =
    earthModel. map( EarthModel: :getPersonModels);
    //
    Optional<Stream<String>> stringStream = personModels .map(per ->
    per stream( ). map(PersonModel:: getName));
    
        / /判断对象 中的list
    Optional .ofNullable(new EarthMode1())
    . map(EarthModel: :getPersonModels)
    .map(pers->pers
    . stream()
    . map(PersonModel: getName)
    .collect(toList())) 
    .ifPresent(per-> System . out .println(per));
    List<PersonModel> models=Data . getData();
    Opt ional .ofNullable(models)
    .map(per -> per
    . stream()
    . map(PersonModel: :getName)
    .collect(toList()))
    . ifPresent(per-> System . out . println(per));
    }
    
    

    并发

    1. stream替换成parallelStream或 parallel
    2. 输入流的大小并不是决定并行化是否会带来速度提升的唯一因素,性能还会受到编写代码的方式和核的数量的影响
    3. 影响性能的五要素是:数据大小、源数据结构、值是否装箱、可用的CPU核数量,以及处理每个元素所花的时间
    不管前方的路有多苦,只要走的方向正确,不管多么崎岖不平,都比站在原地更接近幸福
  • 相关阅读:
    Finding Palindromes POJ
    吉哥系列故事——完美队形II HDU
    Period II FZU
    生日礼物&&Supermarket
    炮兵阵地[状态压缩DP]
    最小表示法 P1368
    Period
    最长异或路径
    Luogu P5490 扫描线
    解方程
  • 原文地址:https://www.cnblogs.com/helloworld-wc/p/13632644.html
Copyright © 2011-2022 走看看