彻底吃透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进行替换,并转换成其他类型的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", "[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 获取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();
回复【666】 获取见面大礼包:当前最火爆的java面试突击.pdf
回复【jvm】 获取jvm指令手册.pdf
回复【架构师】获取全套架构师视频教程
回复 【闲云】获取vue闲云旅游项目实战视频教程
交流合作请扫描二维码: