彻底吃透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");
三、理解流的概念
创建流的几种方式:
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
倒序
自定义排序
//简单类型使用sortedList<String> strings = Arrays.asList("One", "Abc", "Bcd");String sorted1 = strings.stream().sorted().collect(Collectors.joining("\n"));System.out.println(sorted1);//传入comparatorString 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闲云旅游项目实战视频教程
交流合作请扫描二维码:
