java8-Stream

Flow programming model

Generally, the flow is used to operate the collection, and the operation on the collection is realized in a simpler and more efficient way

Get stream from source -- > intermediate operation -- > aggregate stream

We add a series of intermediate operations on the basis of stream to further process the stream. Terminating the operation will gather the stream again. We can choose to count the quantity and average value, or choose to convert them to the state of the set to get a new set

There are three ways to get streams:

支持可变参数
public static<T> Stream<T> of(T... values); 
Arrays.stream(数组)
List<Integer> list = Arrays.asList(1,2,3);
Stream stream4 = list.stream();

Intermediate operation and aggregation operation

If we convert a stream into a specialized stream, such as intstream, sum(), min(), max() have all been implemented for us without rewriting the comparator

For example, the elements in the array are first * 2, and then accumulated and summed

// list是源
List<Integer> list = Arrays.asList(1,3,4,5,6);
System.out.println(list.stream().map(i->i*2).reduce(0,(I,J)->I+J));
System.out.println(list.stream().map(i->i*2).reduce(0,Integer::sum));

collect()

 List<String> list1 = Arrays.asList("hi","你好","hello");
 List<String> collect = list1.stream().collect(Collectors.toList());

As you can see above, through collectors Tolist () brings the stream transformations back together into a collection, not just a list, of course

The aggregation operation is divided into three steps:

list1.stream().collect(()->new ArrayList<String>(),(theList,list1Item)->theList.add(list1Item),(result,list)->result.addAll(list));

Use method references to implement

list1.stream().collect(ArrayList::new,ArrayList::add,ArrayList::addAll);

grouping

Grouping a collection in the way of flow (groupingby()) returns the value map < string, list >

Map<String,List<student>> map = list.stream().collect(Collectors.groupingBy(item -> item.getName()));

Overloaded method of groupingby

Collector<T,?,Map<K,D>> groupingBy(Function<? super T,? extends K> classifier,Collector<? super T,A,D> downstream)`

The second parameter, collector, is also implemented using the static method of collectors. It can perform the next operation for each group, such as calculating the total count(), and calculating the average value, averaging int (tointfunction())

partition

Zoning and grouping go hand in hand:

Collectors: 
Collector<T,Map<Boolean,List<T>>> partitioningBy(Predicate<? super T> predicate)

The input parameter is a predicate type. It accepts a parameter and returns a Boolean value. The partition is actually divided into two groups according to conditions, but now it is called two zone examples:

// 80分以前的为一个区,其他为一个区
Map<Boolean,List<student>> collect1 = list.stream().collect(Collectors.partitioningBy(i -> i.getscore() > 80));

// 低于80分的个数   高于80分的个数
Map<Boolean,Long> collect2 = list.stream().collect(Collectors.partitioningBy(j -> j.getscore() > 80,Collectors.counting()));
System.out.println(collect2);

In the map, ture is the group that meets the conditions, and flash is the group that does not meet the conditions

Flattening of flatmap flow

Example: flatten multiple sets of the same type into a stream to obtain a new set

Stream.of(Arrays.asList(1),Arrays.asList(2,3),Arrays.asList(4,6))
 .flatMap(Collection::stream).map(i->i*i).collect(Collectors.toList()).forEach(System.out::println)

Example: de duplication of elements in a collection

List<String> list = Arrays.asList("hello welcome","world hello","hello welcome world");
list.stream().map(item->item.split(" ")).flatMap(Arrays::stream).distinct().forEach(System.out::println);

When we get here, list stream(). Map (item - > item. Split ("")) its return value type is: stream < string [] > as you can see, the source set is divided into multiple streams according to spaces. Each stream contains complex types and arrays. In this way, if we remove the duplication again, it is actually between arrays, not between elements. Therefore, we need to level the stream < string [] > and convert it into stream < string STR >, In this way, we can achieve our goal

Example: cross printing

List<String> list1 = Arrays.asList("hi","hello");
List<String> list2 = Arrays.asList("wangwu","zhaoliu","zhangsan","lisi");

list1.stream().map(item1->list2.stream().map(item2->item1+"  "+item2)).forEach(System.out::println);

As mentioned above, we did not flatten the stream. We mapped each element item in LIST1 to each element in item + List2, but the nested map has a return value of stream < stream >. In the next internal iteration, we iterated out the stream object of the second layer

So we should level the flow as follows:

list1.stream().flatMap(item1->list2.stream().map(item2->item1+ " "+item2)).forEach(System.out::println);

Conclusion: when the following return conditions occur, consider flatmap and smooth the flow

Other methods of stream

 Stream<String> generate = Stream.generate(UUID.randomUUID()::toString);
 generate.findFirst().ifPresent(System.out::println);
 
 // 若不加限制,创建出无限流
 Stream<Integer> stream = Stream.iterate(1,i -> i + 2).limit(6);

Specialized flow

For example: maptoint (item - > item. Lenth) we can map the item to its length, and then we can filter it in the next step

After converting to a specific stream, you can implement a specific method, which can be used to implement min, Max, sort and AVG operations for specific types

Inert evaluation of flow

Example:

list.stream().map(item -> {
    String result = item.substring(0,1).toUpperCase() + item.substring(1);
    System.out.println("test");
    return result;
}).forEach(System.out::println);

list.stream().map(item -> {
    String result = item.substring(0,1).toUpperCase() + item.substring(1);
    System.out.println("test");
    return result;
});

Referring to the picture at the beginning of the article, stream is used as a resource. We have added a series of intermediate operation maps on the basis of stream to convert the initial letter of each item into uppercase. Terminating the operation foreach will gather the stream again. Where is the inert evaluation of the stream reflected? That is, as long as the stream does not encounter a termination operation, the intermediate operations we add to it will not be executed. As above, we remove foreach() and text will not be printed

In addition, the added termination operation is foreach, which means that she will traverse all elements, and each stream will try to be processed by our intermediate operation; However, it may not always be like this. If we replace foreach with findfirst (), there is no doubt that as long as one unit of stream is successfully processed by all intermediate operations, the operation will stop

This is also the flow execution process. It does not mean that we add 100 intermediate operations in the middle. Each unit stream in the flow has to cycle 100 times before executing the termination operation. On the contrary, there is only one cycle, a cycle composed of 100 intermediate operations

Stream trap

The stream is one-time. After it is used, it cannot be reused. However, if we call the intermediate operation of stream and return a new stream, there will be no exception

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>