Generate flow
In Java8, collection-api provides two method generation streams:
- Stream () − Creates a serial stream for the collection
- ParallelStream () − Creates parallel streams for collections
1.Stream Stream = Lists. NewArrayList (1,2,3).stream(); Stream<Integer> integerStream = Lists. NewArrayList (1, 2, 3).parallelstream (); Stream<Integer> integerStream1 = stream. of(1, 2, 3); 4.Stream<Object> build = stream.builder ().add(1).add(2).add(3).build(); Supplier<Integer> Supplier = new Random()::nextInt; // Generate your own stream. '::' is a reference to a method and Supplier is a function interface. Stream<Integer> generate = Stream.generate(supplier).limit(3);Copy the code
We can also implement a serial stream by customizing the Supplier interface
Private static class MySupplier implements Supplier<Book> {private int index; @Override public Book get() { return new Book("Supplier" + index, new Random().nextInt(1000), index++); } } @Data private static class Book { private String name; private Integer pages; private Integer index; }; public static void main(String[] args) { Stream<Book> limit = Stream.generate(new MySupplier()).limit(3); limit.forEach(System.out::println); Book{name='Supplier1', pages=932, index=0} Book{name='Supplier2', pages=183, index=1} Book{name='Supplier3', pages=201, index=2}Copy the code
List Type Basic operation
Basic operations include looping, filtering, sorting, statistics, merging, de-weighting, and so on
- The loop prints each element in the list; stream() can be omitted
Lists.newArrayList(1, 2, 3).stream().forEach(System.out::println);
Copy the code
- The filter preserves elements greater than 2 in the list and prints them. The filter is a function interface for Predicate, which you can also implement yourself. Similarly, the integer>2 expression can be replaced with any method that returns a Boolean value, with true preserving the element.
Lists.newArrayList(1, 2, 3).stream().filter(integer -> integer > 2).forEach(System.out::println);
Copy the code
- Sort defaults to sort in natural order and the output is 2,6,9,11,33
- The sorted() method customizes a class that implements the Comparator interface for custom sorting
Lists. NewArrayList (11, 2, 33,6,9) stream (). The sorted (); Stream.generate(new MySupplier()).limit(3).sorted(new Comparator<Book>() { @Override public int compare(Book o1, Book o2) { return o1.getPages() - o2.getPages(); }}); Sorted ((o1, O2) -> o1.getPages() -o2.getPages ()); 3. Sorted (Comparator.comparingInt(Book::getPages)); Book{name='Supplier', pages=4, index=2} Book{name='Supplier', pages=28, index=0} Book{name='Supplier', pages=883, index=1}Copy the code
- statistical
ArrayList<Integer> numbers = Lists.newArrayList(11, 2, 33, 6, 9); IntSummaryStatistics intSummaryStatistics = numbers.stream().mapToInt(x -> x).summaryStatistics(); System. The out. Println (" the biggest number in the list: "+ intSummaryStatistics. GetMax ()); System. The out. Println (" the smallest number in the list: "+ intSummaryStatistics. GetMin ()); System. The out. Println (" is the sum of all Numbers: "+ intSummaryStatistics. GetSum ()); System. The out. Println (" is mean: "+ intSummaryStatistics. GetAverage ());Copy the code
- Merge list flow
Static method of Stream Stream. Concat (stream1 stream2) can synthesize two flows a Stream of static methods Stream. Of (stream1 stream2, stream3… Stream) can form a list of N streams, and then use the flatMap method to merge each stream in the list
ArrayList<Integer> list1 = Lists.newArrayList(1, 2, 3, 4); ArrayList<Integer> list2 = Lists.newArrayList(5, 6, 7, 8); ArrayList<Integer> list3 = Lists.newArrayList(9, 10, 11, 12); List<Integer> concat = Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList()); System.out.println(StringUtils.join(concat,",")); List<Integer> collect = Stream.of(list1.stream(),list2.stream(),list3.stream()).flatMap(item -> item).collect(Collectors.toList()); System.out.println(StringUtils.join(collect,",")); / / output,2,3,4,5,6,7,8 1,2,3,4,5,6,7,8,9,10,11,12Copy the code
- To retry
The distinct() method of Stream can be used directly to return a new Stream for data of underlying types. For custom objects, the equals() method needs to be overridden
ArrayList < Integer > = distinct Lists. NewArrayList,1,2,2,2,3,4,5,5 (1); List<Integer> distinctList = distinct.stream().distinct().collect(Collectors.toList()); System.out.println(StringUtils.join(distinctList,","));Copy the code
- Reduce the operating
Reduce is an aggregation operation whose input is the BinaryOperator function interface and has a default apply method that takes two values and produces a new value. It means to aggregate all the elements of a stream into a single result according to the aggregation function
@FunctionalInterface public interface BiFunction<T, U, R> { R apply(T t, U u); } ArrayList<Integer> reduce = Lists. NewArrayList (1,1,2,2,2,3,4,5,5); Integer reduceResult = reduce.stream().reduce(Integer::sum).orElse(0);Copy the code
- The skip/limit operation
Limit returns the first n elements of the stream; Skip is to skip n elements of stream; Both return a new stream
The 2021-2-28
List type fancy operation
- Turn the List Map > < K, V
List<Book> bookList = Lists. NewArrayList (new Book(" language ",10,1),new Book(" math ",20,2),new Book(" English ",30,3),new The Book (" English ", 40, 4)); LinkedHashMap<String, Book> bookMap = bookList.stream().collect(Collectors.toMap(Book::getName, books -> books, (old, news) -> old, LinkedHashMap::new));Copy the code
The Collectors static method toMap, which outputs a stream in map format, has four function interface inputs.
- The first keyMapper is the method that generates the map’s Key. The above example uses the Name attribute of the Book class as the map’s Key
- The second valueMapper is the value method that generates the map. In the example above, the entire Book object is used as the value of the map
- The third mergeFunction is the corresponding strategy method when the same key appears in the map generation process. In the above example, the previous key/value is retained and the new one is discarded.
- The fourth mapSupplier is the map type of the returned value. In the example above, an empty linkedHashMap is passed in and the resulting result is filled into the map. It must be a Map type because the static method declaration defines the generic M to inherit from the Map
public static <T, K, U, M extends Map<K, U>> Collector<T, ? , M> toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier) { BiConsumer<M, T> accumulator = (map, element) -> map.merge(keyMapper.apply(element), valueMapper.apply(element), mergeFunction); return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID); }Copy the code
- List the group
List<Book> bookList = Lists. NewArrayList (new Book(" language ",10,1),new Book(" math ",25,2),new Book(" English ",20,3),new The Book (" physics ", 40, 4)); Map<String, List<Book>> bookMapByName = bookList.stream().collect(Collectors.groupingBy(Book::getName));Copy the code
GroupingBy, a static method, can group data by a property. Similar to group BY in SQL, the groupingBy method has three interfaces
public static <T, K, D, A, M extends Map<K, D>> Collector<T, ? , M> groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream) ;Copy the code
- The first classifier function uses the input as the grouping key. In the example above, the name attribute of book is used as the grouping key.
- The second mapFactory function is the type of map that will be output, which in the example above is the default HashMap.
- The third downstream function does downstream operations that can be nested, which in the example above is the default to generate a list
1. Group by index. List<Book> bookList = Lists. NewArrayList (new Book(" language ",10,1),new Book(" math ",21,2),new Book(" English ",30,2),new The Book (" physics ", 40, 4)); Map<Integer, List<String>> collect2 = bookList.stream().collect(Collectors.groupingBy(Book::getIndex, Collectors.mapping(Book::getName, Collectors.toList()))); 2. Double groups by page number, groups larger than 20 pages, List<Book> bookList = Lists. NewArrayList (new Book(" language ",10,1),new Book(" math ",21,2),new Book(" English ",30,3),new The Book (" physics ", 40, 4)); Map<Boolean, List<String>> collect1 = bookList.stream().collect(Collectors.partitioningBy(item -> item.getPages() > 20, Collectors.mapping(Book::getName, Collectors.toList()))); {false=[language], true=[math, English, physics]}Copy the code