vlambda博客
学习文章列表

彻底吃透java函数式编程

  彻底吃透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");

彻底吃透java函数式编程

三、理解流的概念

创建流的几种方式:

  • 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进行替换,并转换成其他类型的mapTreeMap<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));  //分组并转换成dtoMap<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", "[email protected]");  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 protected]

九、排序

  • 简单类型使用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 获取listList<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();


程序工厂充电宝 发起了一个读者讨论 大家在平时的项目开发中是否喜欢用函数式编程呢

回复【666】 获取见面大礼包:当前最火爆的java面试突击.pdf

回复【jvm】 获取jvm指令手册.pdf

回复【架构师】获取全套架构师视频教程

回复 【闲云】获取vue闲云旅游项目实战视频教程

交流合作请扫描二维码: