Page GitHub: http://blog.cloudli.top/posts/Java- functional programming - stream operation /
External iteration to iteration inside
When using the collection classes, the common way is to use for
a set of loop iterations, and each processing element. For example, to calculate the collection user from Shanghai:
int count = 0;
for (User user : allUsers) {
if (user.isFrom("Shanghai")) {
count++;
}
}
The above code is external iteration, in such a way to write a lot of boilerplate code.
Another way is internal iteration:
long count = allUsers.stream()
.filter(user -> user.isFrom("Shanghai"))
.count();
The whole process into a function call, and is decomposed into two simple operations:
- Identify all users from Shanghai.
- Calculate their number.
Each operation corresponds to Stream
a method interface. In order to find out the user from Shanghai, the need for Stream
object filtering: filter()
method, which accepts a lambda expression, and finally by the count()
method of calculating a given Stream
number of objects included.
Only call filter()
method does not do anything:
allUsers.stream()
.filter(user -> {
out.println(user.name);
return user.isFrom("Shanghai")
});
The above code will not produce any output, only the last call count()
methods in order to see the output. filter
The method returns an Stream
object of this process and the builder pattern is similar.
The builder pattern set properties through a series of operations, only the last call to the build()
method of the object will be created. In this filter()
method simply pass a lambda expression, only the count()
will to enforce it when the method is called.
Common operation flow
filter
filter()
The method has appeared on a portion, which uses a lambda expression elements given inspection flow, and display the required elements.
List<User> usersFromShanghai = allUsers.stream()
// 过滤出来自上海的用户
.filter(user -> user.isFrom("Shanghai"))
.collect(Collectors.toList());
filter()
Parameter method is Predicate
the interface:
collect
The method accepts a Collector
type of interface function. It may be combined with Collectors
the methods provided to complete the operation.
All users from Shanghai into a list:
List<User> usersFromShanghai = allUsers.stream()
.filter(user -> user.isFrom("Shanghai"))
.collect(Collectors.toList());
The number of regional statistics for each user, and SQL in this operation group by
is similar. :
Map<String, Long> userMap = allUsers.stream()
// 以 User 的 location 进行分组,对每个分组计数
.collect(Collectors.groupingBy(User::getLocation, Collectors.counting()));
collect()
The method can also do a lot of operations, more than just one.
map
map()
Values can be converted to a stream in a new stream.
All will be a list of strings to upper case:
List<String> list = Stream.of("a", "b", "c")
// 将每个字符串转换成大写
.map(str -> str.toUpperCase())
// 转换为列表
.collect(Collectors.toList());
Here we pass map()
the lambda expression to accept a String
type of argument and returns a new one String
. Parameters and return values may not be of the same type.
map()
Method parameters are Function
a function of interface:
flatMap
flatMap()
The value of each of a stream are converted to Stream
the object.
This method may be used to merge multiple lists:
List<Integer> together = Stream.of(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6))
// 将每个列表都转换成 Stream
.flatMap(numbers -> numbers.stream())
// 转换成列表
.collect(Collectors.toList());
flatMap()
Parameters of the method is Function
an interface, the only difference is that the return value is defined Stream
type.
reduce
reduce()
The method may be implemented to generate a value from a set of values.
For a list of sums:
int sum = Stream.of(1, 2, 3, 4)
.reduce(0, (acc, e) -> acc + e);
For a list of factorial:
int sum = together.stream()
.reduce(1, (acc, e) -> acc * e);