彻底吃透java8函数式编程

举报
小米粒-biubiubiu 发表于 2020/10/13 14:39:09 2020/10/13
【摘要】 彻底吃透java8函数式编程

                                               彻底吃透java8函数式编程

目录

一、Lamda表达式

二、java函数式接口

三、理解流的概念

四、常见操作符

五、Optional - 和null说再见

六、集合对象收集器

七、分组统计和聚合函数

八、其他操作:

九、排序

十、flatMap处理流的嵌套

十一、Reduce



一、Lamda表达式

箭头左边是参数列表,右边是函数体。

方法引用 : class::method

  • 静态方法引用:  User::combine  

  • 参数方法引用:  String::indexOf

  • 实例方法引用:  user::getUserName

  • 构造器引用: User::new

二、java函数式接口

有且仅有一个未实现的非静态方法的接口叫做“函数式接口”

interface IProducer<T>{
    T produce();
}

// ()=>User.builder().id(100L).name("imooc").build();


interface IConfigurator<T>{
    void configure(T t);
}

//(user) -> user.setMobile("13657065000");

image.png

image.png三、理解流的概念

image.png

创建流的几种方式:

  • Arrays.stream(T[] array)

Arrays.stream(arrayOfUsers)
      .peek(user->log.debug("user:{}",user.getUsername()))
      .collect(toList())

  • Collection.stream()

userList.stream()
      .peek(user->log.debug("user:{}",user.getUsername()))
      .collect(toList())

  • Stream.of(T... values)

List<String> strList = Stream.of("1","2","3").peek(o->log.info(o)).collect(toList())

  • Stream.iterate

Stream.iterate(0,n->n+1).limit(10)
      .peek(n->log.debug("the number is:{}",n))
      .collect(Collector.toList())

  • Stream.generate

List<Integer> list = Stream.generate(()->Math.random())
                            .limit(10)
                            .peek(n->log.debug("the number is:{}",n))
                            .collect(Collectors.toList())

  • StreamSupport.stream

Iterator irt = userList.iterator();
Splitator<User> splitator = Spliterators.spliteratorUnknowSize(itr,Spliterator.NONNULL);
Stream<User> userStream = StreamSupport.stream(splitator,false);
List<User> userList =  userStream.peek(user->log.debug("user:{}",user.getUsername()))
                                 .collect(Collectors.toList());

  • IntStream

List<Integer> list = IntStream.range(0,5).boxed().peek(i->log.debug("the number is:{}",i))
                              .collect(Collectors.toList()) 

//输出结果: 0,1,2,3,4
//如果使用rangeClosed(0,5)则是闭区间,输出:0,1,2,3,4,5

  • Stream.builder()

List<Integer> list = Stream.builder().add(1).add(2).add(3).build().skip(1).peek(...)
.collect(Collectors.toList);

四、常见操作符

filter,map ,peek,findAny,findFirst

foreach,anyMatch,noneMatch

count, min, max

五、Optional - 和null说再见

isPresent, isEmpty

orElse,orElseGet,  orElseThrowl, or

ifPresent, ifPresentOrElse

六、集合对象收集器

toList  ,toSet,toMap,toCollection

List<String> list = userList.stream().map(User::getName).collect(Collectors.toList());
Set<String> set = userList.stream().map(User::getName).collect(Collectors.toSet());
Map<String,User> map = userList.stream().map(User::getName).collect(Collectors.toMap(
  User::getName,
  user->user
));

//如果存在相同的key,是否将其value进行替换
Map<String,User> map = Stream.concat(userList.stream(),userList.stream())
                             .peek(user->log.debug("username,{}",user.getUserName))
                             .collect(Collectors.toMap(
                                User::getUsername,
                                user->user,
                                (existing,replace)->existing,
                             ))      

//如果存在相同的key,是否将其value进行替换,并转换成其他类型的map
TreeMap<String,User> treeMap = Stream.concat(userList.stream(),userList.stream())
                             .peek(user->log.debug("username,{}",user.getUserName))
                             .collect(Collectors.toMap(
                                User::getUsername,
                                user->user,
                                (existing,replace)->existing,
                                TreeMap::new
                             ))  

Comparator<User> byAge = Comparator.comparing(User::getAge);
TreeSet<User> users = userList.stream().collect(Collectors.toCollection(()->new TreeSet(byAge)));

users.stream().map(User::getAge).findFirst().orElse(-1);

七、分组统计和聚合函数

聚合计算:

averagingXXX , 求平均值

summingXXX,   求和

summarizingXXX 一次性求出平均值,和,记录数,最大值,最小值

maxBy ,       

counting 

分组统计: groupingBy

//求平均值
double age = userList.stream.collect(Collectors.averagingDouble(User::getAge));

//求和
double sum = userList.stream.collect(Collectors.summingDouble(User::getAge));
        stat.getCount();
        stat.getAverage();
        stat.getMax();
        stat.getMin();
        stat.getSum();

//一次性求出记录数,平均值,最大值,最小值,和
DoubleSummaryStatistics stat = userList.stream.collect(Collectors.summarizingDouble(User::getAge));
        stat.getCount();
        stat.getAverage();
        stat.getMax();
        stat.getMin();
        stat.getSum();

//分组
Map<Integer,List<User>> map = userList.stream.collect(Collectors.groupingBy(user->(int)Math.floor(user.getAge/10)));

//分组统计
Map<Integer,DoubleSummaryStatistics> map = userList.stream.collect(Collectors.groupingBy(user->(int)Math.floor(user.getAge/10)),Collectors.summarizingDouble(User::getAge));


//分组并转换成dto
Map<Integer,List<UserDto>> map = userList.stream.collect(Collectors.groupingBy(
        user->(int)Math.floor(user.getAge/10),
        mapping(user->new UserDto(user.getId(),user.getUsername()),
        Collectors.toList())
))

八、其他操作:

mapping:

collectingAndThen:

joining:

List<String> list =  List.of("a","b","c");
//mapping 操作
list.stream().collect(groupingBy(
                        String::length,
                        mapping(String::toUpperCase,
                               filtering(
                                    s->s.length>1,
                                    toCollection(TreeSet::new)
                                ) 
                            ) 
                        ))

//collectingAndThen 操作:其实就是在最后再做一个单一操作
list.stream().collect(groupingBy(
                        user-> (int)Math.floor(user.getAge/10)*10,
                        mapping(String::toUpperCase,
                               collectingAndThen(
                                    toList(),
                                    list->{
                                    double average=                      list.stream.collect(averagingDouble(User::getAge));
                                    return new UserStat(average,list);                    
                                    }
                                ) 
                            ) 
                        ))

//join操作

Map<String,String> map = new HashMap<>(3);
        map.put("name", "张三");
        map.put("age", "23");
        map.put("email", "414591005@qq.com");

        String url = map.keySet().stream().map(key -> key + "=" + map.get(key)).collect(Collectors.joining("&",
                "http://localhost:8080/selectInfo?", ""));

        System.out.println(url); 
//http://localhost:8080/selectInfo?name=张三&age=23&email=414591005@qq.com

九、排序

  • 简单类型使用sorted

  • sorted可以传入comparator

  • 倒序

  • 自定义排序

       //简单类型使用sorted
 List<String> strings = Arrays.asList("One", "Abc", "Bcd");
        String sorted1 = strings.stream().sorted().collect(Collectors.joining("\n"));
        System.out.println(sorted1);

        //传入comparator
        String sorted2 = strings.stream().sorted(String::compareTo).collect(Collectors.joining("\n"));
        System.out.println(sorted2);

        //倒序
        String sorted3 = strings.stream().sorted(Comparator.reverseOrder()).collect(Collectors.joining("\n"));
        System.out.println(sorted3);

        //自定义排序
        String sorted4 = strings.stream().sorted(Comparator.comparing(s -> s.length(), (o1, o2) -> o1.compareTo(o2))).collect(Collectors.joining("\n"));
        System.out.println(sorted3);

十、flatMap处理流的嵌套

父子对象常见的集合属性

List<Role> roleList =  userList.stream().flatMap(user->user.getRoles().stream())
                 .peek(role->log.debug("role:{}",role))
                 .collect(toList());

 在流中产生了optional元素

//java9中的新特性: optional新增的stream()方法
List<User> list = userList.stream().map(user->Api.findByUserName(user.getUsername))
                .flatMap(Optional::stream)
                .peek(profile->log.debug("profile:{}",profile))
                .collect(toList());

十一、Reduce

执行归集操作-某种程度上和collect作用类似

//reduce求和
Integer sumByReduce = userList.stream().map(user.getAge)
                              .reduce(0,Integer::sum);

//reduceq求最大(最小)值
Optional<User> userOptional = userList.stream().reduce((acc,curr)->{return acc.getId()>curr.getId()?acc:curr});

userOptional.get().getId();


//reduce 获取list
List<User> userList = userList.parallelStream().reduce(
    Collections.emptyList(),
    (acc,curr)->{
    List<User> newAcc = new ArrayList<>();
    newAcc.addAll(acc);
    newAcc.add(curr);
    return newAcc;
    },
    //combiner这个函数的作用主要是考虑并行流,并行流的情况下,一个流会分成多个分片进行处理,
    //每一个分片会产生一个临时的中间结果,combiner的作用就是把这些中间结果在合并成一个最终结果
    (left,right)->{
    List<User> merged = new ArrayList<>();
    merged.addAll(left);
    merged.addAll(right);
    return megred;            
    }
)

 collect的方式进行累加操作

        //参数一:创建一个容器
        //参数二:向容器添加元素
        //参数三: 容器中的元素累加
MutableInt sumByCollect = userList.stream().collect(
                MutableInt::new,
               (MutableInt container,User user)->container.add(user.getAge),
                MutableInt::add
               )

MutableInt collect1 = numList.stream().collect(MutableInt::new, MutableInt::add,                         MutableInt::add);

String concat = numList.stream().collect(StringBuilder::new, StringBuilder::append,
                StringBuilder::append).toString();


【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。