It is very frequent to operate set data in programming. Using Stream in Java8 to deal with set, combined with Lambda functional programming, can greatly simplify the code. Rational use of Stream can improve the readability of code. There are a lot of relevant performance test cases on the Internet for reference. If someone says to you: Lambda has some problems such as poor readability and high maintenance cost, you can rest assured. Please be sure to take a look at the last points of attention

1. The Stream created

The following Lists use the Google Guava API, directly from the code:

Stream.of("A", "B"); Stream<String> stream1 = stream. of("A", "B"); Stream<String bb0 stream2 = lists.neWarRayList ("A", "B").stream(); Stream<String> stream3 = Sets.newHashSet("A", "B").stream(); Stream<String> stream4 = array. Stream (new String[]{"A", "B"}); // Paths <String> stream5 = files.lines (Paths. Get ("/file.text")); Stream (new Int [] {1, 2, 3}); Stream (new Int [] {1, 2, 3}); // create Stream<Object bb0 stream7 = stream.builder ().add("A").build();

ParallelStream is a parallelStream, and parallelStream is a parallelStream. Parallel is a parallelStream, and parallelStream is a parallelStream. Parallel is a parallelStream, and parallelStream is a parallelStream.

Streams <String bb0 stream1 = lists.neWarRayList ("A", "B").parallelStream(); Stream (new String[]{"A", "B"}).parallel(); Stream (new String[]{"A", "B"}).parallel();

2. Intermediate Stream operation

MapToInt, MapToLong, MapToDouble can be converted directly to IntStream, LongStream, DoubleStream. Map can be converted directly to IntStream, LongStream, DoubleStream. Map can be converted to IntStream, LongStream, DoubleStream.

-n List<String> result1 = lists.neWarRayList ("A").stream().map(item-> item +) "-N").collect(Collectors.toList()); List<String[]> result2 = lists.neWarRayList ("A").stream().map(item-> new).result2 = lists.neWarRayList ("A").stream().map(item-> new).result2 = lists.neWarRayList ("A").result2 String[]{item}).collect(Collectors.toList());

Stream.FlatMap to merge multiple streams into a single Stream is often used to merge multiple lists of data

List<String> result = Lists.newArrayList(
        Lists.newArrayList("A"),
        Lists.newArrayList("B")
).stream().flatMap(Collection::stream).collect(Collectors.toList());

The stream. filter element can replace the if judgment condition in the loop, and the parameter is a logical expression

List<String> result = Lists.newArrayList("A", "B")
        .stream().filter("A"::equals).collect(Collectors.toList());

Stream. DISTINCT elements to duplicate. Typically used for simple data types, TreeSet can be used to duplicate objects as follows

List<String> result1 = Lits.neWarRayList ("A", "A", "B").stream().distinct(). Collect (Collectors.tolist ()); List<Demo> result2 = lists.neWarRayList (new Demo()).stream().collect().result2 = lists.neWarRayList (new Demo()).stream().collect().result2 = lists.neWarRayList ().result2 Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(comparing(Demo::getName))), ArrayList::new) );
@Data
class Demo {
    private String name;
    private String age;
}

Stream.peek only processes data and does not change the original data type. Unlike map, peek accepts an operation that does not return a value, and is used to modify the internal elements of an object

List<Demo> result = Lists.newArrayList(new Demo())
        .stream().peek(item -> item.setName("A")).collect(Collectors.toList());

Stream.sorted sorts data, supports positive and reverse ordering, and supports sorting of object-type data

// List<String> result1 = lists.neWarRayList ("A", "B").stream().sorted(). Collect (Collectors.tolist ()); // The object type is sorted by an attribute, the default is positive order, List<Demo> result2 = lists.neWarRayList (new Demo()) .stream().sorted(Comparator.comparing(Demo::getName).reversed()).collect(Collectors.toList());

Stream.limit limits the amount of final output data, and intercepts elements in the Stream. By default, no intercepting is performed

List<String> result1 = Lists.newArrayList("A", "B")
        .stream().limit(1).collect(Collectors.toList());

Skip the previous number of elements, similar to limit, which returns a Stream as soon as it reaches a limit

List<String> result = Lists.newArrayList("A", "B")
        .stream().skip(1).collect(Collectors.toList());

3. Stream terminates the operation

Collect data for the collection stream, which is being received by the Collectors. Tolist (List) and the Collectors. Joining (String)

ListList <String> result1 = Lits.neWarRayList ("A", "B").stream(). Collect (Collectors.tolist ()); // Collect data as String, default delimiter, You can specify the delimiter String result2 = Lits.neWarRayList ("A", "B").stream().Collect (Collectors.joining());

Reduce data is aggregated into a value. After the data is converted into a single value, a final value is calculated, which has been accumulated here as an example

BigDecimal result = Lists.newArrayList(BigDecimal.valueOf(1), BigDecimal.valueOf(2)).stream().reduce(BigDecimal.ZERO, BigDecimal::add);

Allmatch, Anymatch, Nonematch

Returns true Boolean result1 = lists.neWarRayList (1, 2, 3, 4).stream(). AllMatch (item-> item > 1); // Returns true Boolean result2 = lists.neWarRayList (1, 2, 3, 4).stream(). AnyMatch (item-> item > 1); // Returns true Boolean result3 = Lits.neWarRayList (1, 2, 3, 4).stream(). NoneMatch (item-> item > 1);

The number of values for the COUNT statistic

long result1 = Lists.newArrayList(1, 2, 3, 4).stream().count();

The difference is that in parallel processing, findAny will return the first item after matching the data, while findFirst will return the first item after all data processing is completed. Therefore, findAny is more efficient in parallel processing

Result1 = lists.neWarRayList (1, 2, 3, 4).stream().findAny().get(); Result12 = Lits.neWarRayList (1, 2, 3, 4).ParallelStream ().findFirst().get();

Foreach, ForeachOrdered iterates over all elements, such as output operations. With forEach, why do we need ForeachOrdered? In parallel execution, elements are executed out of order

List.neWarRayList (1, 2, 3, 4).stream().foreach (System.out::println); list.neWarRayList (1, 2, 3, 4).stream(). Lists. NeWarRayList (1, 2, 3, 4).ParallelStream ().ForeachOrdered (System.out::println);

Max and min get the maximum and minimum values of the elements in the stream. The following example shows that the maximum value is worth obtaining, and the minimum value is the same

// Integer result = list.neWarRayList (1, 2, 3, 4).stream().max(Integer:: Compare).get(); Demo result = lists.neWarRayList (new Demo()).stream().max(Demo::getAge)).get();

4. Watch your Stream

When using parallel streams for processing, the final data must be collected, otherwise the data may be lost, such as collect or reduce to collect data, that is to say, use collect and reduce to use parallelStream, then the whole stream processing is thread safe