Thoroughly understand java8 functional programming
table of Contents
Two, java functional interface
Three, understand the concept of flow
Five, Optional-say goodbye to null
Six, collection object collector
Seven, group statistics and aggregation functions
Ten, flatMap handles the nesting of streams
One, Lamda expression
The left side of the arrow is the parameter list, and the right side is the function body.
Method reference: class::method
- Static method reference: User::combine
- Parameter method reference: String::indexOf
- Instance method reference: user::getUserName
- Constructor reference: User::new
Two, java functional interface
An interface with one and only one unimplemented non-static method is called a "functional interface"
interface IProducer<T>{
T produce();
}
// ()=>User.builder().id(100L).name("imooc").build();
interface IConfigurator<T>{
void configure(T t);
}
//(user) -> user.setMobile("13657065000");
Three, understand the concept of flow
Several ways to create a stream:
- 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);
Four, common operators
filter,map ,peek,findAny,findFirst
foreach , anyMatch , noneMatch
count, min, max
Five, Optional-say goodbye to null
isPresent, isEmpty
orElse,orElseGet, orElseThrowl, or
ifPresent, ifPresentOrElse
Six, collection object collector
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);
Seven, group statistics and aggregation functions
Aggregate calculation:
averagingXXX, find the average
summingXXX, sum
summarizingXXX Find the average, sum, number of records, maximum and minimum values at one time
maxBy ,
counting
Grouping statistics: 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())
))
8. Other operations:
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]
Nine, sort
- Simple types use sorted
- sorted can be passed to the comparator
- Reverse order
- Custom sort
//简单类型使用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);
Ten, flatMap handles the nesting of streams
Common collection properties of parent-child objects
List<Role> roleList = userList.stream().flatMap(user->user.getRoles().stream())
.peek(role->log.debug("role:{}",role))
.collect(toList());
Optional elements are produced in the stream
//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());
11. Reduce
Perform collection operations-to some extent similar to 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;
}
)
Accumulate operation in the collect method
//参数一:创建一个容器
//参数二:向容器添加元素
//参数三: 容器中的元素累加
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();