Introduction to splitter in Java 8 stream

Introduction to splitter in Java 8 stream

brief introduction

Splitter is an interface introduced in Java 8. It is usually used with stream to traverse and segment sequences.

Splitter is required wherever stream is used, such as list, collection, IO channel, etc.

Let's first look at the definition of the stream method in the collection:

default Stream<E> stream() {
        return StreamSupport.stream(spliterator(),false);
    }
default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(),true);
    }

We can see that both parallel and non parallel streams are constructed through streamsupport, and a splitter parameter needs to be passed in.

Well, after we know what the splitter does, let's take a look at its specific structure:

The splitter has four methods that must be implemented. We will explain them in detail next.

tryAdvance

Tryadvance is a method to process elements in the stream. If an element exists, it will be processed and returned true. Otherwise, it will return false.

If we don't want to process the subsequent elements of the stream, we can return false in tryadvance. Using this feature, we can interrupt the processing of the stream. This example will be discussed in a later article.

trySplit

Trysplit attempts to split the existing stream, which is generally used in the case of parallel stream, because in a concurrent stream, we need to use multiple threads to process different elements of the stream. Trysplit is the method to split the elements in the stream.

Ideally, trysplit should split the stream into two equal parts to maximize performance.

estimateSize

Estimatesize indicates the elements to be processed in the splitter. It is generally different before and after trysplit. We will explain it in specific examples later.

characteristics

Characteristics represents the characteristics of the splitter. The splitter has eight characteristics:

public static final int ORDERED    = 0x00000010;//表示元素是有序的(每一次遍历结果相同)
public static final int DISTINCT   = 0x00000001;//表示元素不重复
public static final int SORTED     = 0x00000004;//表示元素是按一定规律进行排列(有指定比较器)
public static final int SIZED      = 0x00000040;//
表示大小是固定的
public static final int NONNULL    = 0x00000100;//表示没有null元素
public static final int IMMUTABLE  = 0x00000400;//表示元素不可变
public static final int CONCURRENT = 0x00001000;//表示迭代器可以多线程操作
public static final int SUBSIZED   = 0x00004000;//表示子Spliterators都具有SIZED特性

A splitter can have multiple features, and multiple features can be or operated to obtain the final characteristics.

for instance

We discussed some key methods of splitter above. Now let's take a specific example:

@AllArgsConstructor
@Data
public class CustBook {
    private String name;

}

First define a custbook class and put a name variable in it.

Define a method to generate a custbook list:

    public static List<CustBook> generateElements() {
        return Stream.generate(() -> new CustBook("cust book"))
                .limit(1000)
                .collect(Collectors.toList());
    }

We define a call method, calling the tryAdvance method in the call method, and passing in our custom processing method. Here we modify the name of the book and attach additional information.

    public String call(Spliterator<CustBook> spliterator) {
        int current = 0;
        while (spliterator.tryAdvance(a -> a.setName("test name"
                .concat("- add new name")))) {
            current++;
        }

        return Thread.currentThread().getName() + ":" + current;
    }

Finally, write the test method:

    @Test
    public void useTrySplit(){
        Spliterator<CustBook> split1 = SpliteratorUsage.generateElements().spliterator();
        Spliterator<CustBook> split2 = split1.trySplit();

        log.info("before tryAdvance: {}",split1.estimateSize());
        log.info("characteristics {}",split1.characteristics());
        log.info(call(split1));
        log.info(call(split2));
        log.info("after tryAdvance {}",split1.estimateSize());
    }

The results of the operation are as follows:

23:10:08.852 [main] INFO com.flydean.SpliteratorUsage - before tryAdvance: 500
23:10:08.857 [main] INFO com.flydean.SpliteratorUsage - characteristics 16464
23:10:08.858 [main] INFO com.flydean.SpliteratorUsage - main:500
23:10:08.858 [main] INFO com.flydean.SpliteratorUsage - main:500
23:10:08.858 [main] INFO com.flydean.SpliteratorUsage - after tryAdvance 0

The list has 1000 pieces of data in total. After calling trysplit once, the list is divided into two parts with 500 pieces of data in each part.

Note that after the tryadvance call, the estimatesize changes to 0, indicating that all elements have been processed.

Let's take another look at this character = 16464, which is converted to hexadecimal: ox4050 = ordered or sized or subsized.

This is also the basic feature of ArrayList.

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
分享
二维码
< <上一篇
下一篇>>