After the flow operation is complete, you can collect data from the flow if you need to save the results of the flow to an array or collection

Puts the results of the Stream Stream into the collection

Stream flow provide collect method and its parameters requires A Java. Util. Stream. The Collector < T, A, R > interface object to specify the collected that combination. Java. Util. Stream. The Collectors class provides methods and can be used as a Collecto the instance of the interface:

  • public static <T> Collector<T, ? , List<T>> toList(); convertListA collection of
  • public static <T> Collector<T, ? , List<T>> toSet(); convertSetA collection of
public void testStreamToCollection(a){
        List<String> one = new ArrayList<>();
        Collections.addAll(one ,"Xenzhao".Wu Zetian."Concubine"."Xiang"."Master of evil.");
        // Collect the collection from the stream into the collection
        List<String> toList = one.stream().collect(Collectors.toList());
        Set<String> toSet = one.stream().collect(Collectors.toSet());
   			// Collect to the specified collection
        ArrayList<String> arrList = one.stream().collect(Collectors.toCollection(ArrayList::new));
        HashSet<String> hashSet = one.stream().collect(Collectors.toCollection(HashSet::new));
  			// Collect the collection from the stream into an array
        String[] array = one.stream().toArray(String[]::new);
    }
Copy the code

The data in the flow are aggregated

When we use a Stream Stream to process data, we can operate on a field like a database aggregate function. For example, get Max, min, sum, average, statistic, etc.

public void testStreamToOther(a){
        Stream<Person> personStream = Stream.of(
                new Person("The sable cicada".18),
                new Person("Wang Zhaojun".21),
                new Person("Beauty".19),
                new Person("Yang Yuhuan".20));
        // Get the maximum value
        Optional<Person> max = personStream.collect(Collectors.maxBy((s1, s2) -> s1.getAge() - s2.getAge()));
        / / the minimum
        Optional<Person> min = personStream.collect(Collectors.minBy((s1, s2) -> s1.getAge() - s2.getAge()));
        / / sum
        Integer sum = personStream.collect(Collectors.summingInt(s -> s.getAge()));
        / / the mean
        Double avg = personStream.collect(Collectors.averagingInt(s -> s.getAge()));
        // Count the quantityLong count = personStream.collect(Collectors.counting()); }}Copy the code

Group the data in the stream

When we process data using a Stream, we can group the data according to an attribute:

public void testStreamGroup(a){
        Stream<Person> personStream = Stream.of(
                new Person("The sable cicada".18),
                new Person("Wang Zhaojun".20),
                new Person("Beauty".19),
                new Person("Yang Yuhuan".20));
        // Group by age
        Map<Integer, List<Person>> ageMap = personStream.collect(Collectors.groupingBy(s -> s.getAge()));
        Map<Integer, List<Person>> ageMap2 = personStream.collect(Collectors.groupingBy(Person::getAge));
        // By age
        Map<String, List<Person>> ageMap3 = personStream.collect(Collectors.groupingBy(e -> {
            if (e.getAge() > 19) {
                return "Young";
            } else {
                return "Older"; }})); }Copy the code

Multilevel grouping of data in the stream

public void testStreamGroup2(a){
        Stream<Person> personStream = Stream.of(
                new Person("The sable cicada".19),
                new Person("Wang Zhaojun".20),
                new Person("Beauty".19),
                new Person("Yang Yuhuan".20));
        // Group by age first, then group by name
        //groupingBy(Function<? super T, ? extends K> classifier,Collector<? super T, A, D> downstream)
        Map<Integer, Map<String, List<Person>>> collect = personStream.collect(Collectors.groupingBy(Person::getAge,
                Collectors.groupingBy(e -> {
            if (e.getAge() > 19) {
                return "Young";
            } else {
                return "Older"; }}))); System.out.println("collect:"+collect.toString());
    }
Copy the code

Partition the data in the stream

Collectors.partitioningByThe collection is split into two lists, a true list and a false list, depending on whether it is true

public void testStreamPartition(a){
        Stream<Person> personStream = Stream.of(
                new Person("The sable cicada".19),
                new Person("Wang Zhaojun".20),
                new Person("Beauty".19),
                new Person("Yang Yuhuan".20));
        Map<Boolean, List<Person>> collect = personStream.collect(Collectors.partitioningBy(e -> {
            return e.getAge() > 19;
        }));
        System.out.println("collect:"+collect.toString());
    }
Copy the code

The data in the flow is spliced

Collectors. Joining joins all elements into a string based on the specified connector.

public void testJoin(a){
        Stream<Person> personStream = Stream.of(
                new Person("The sable cicada".19),
                new Person("Wang Zhaojun".20),
                new Person("Beauty".19),
                new Person("Yang Yuhuan".20));
        // Concatenate according to a string
        String names = personStream.map(Person::getName).collect(Collectors.joining("_"));
        // Concatenate three strings, delimiter, prefix, suffix
        personStream.map(Person::getName).collect(Collectors.joining("_"."AA"."BB"));
        System.out.println("names:"+names);
    }
Copy the code

Parallel Stream streams

A serial Stream

    public void testSerial(a){
        Stream.of(1.4.6.7.8.9.2.3).filter(e->{
            System.out.println(Thread.currentThread()+"... ""+e);
            return e>3;
        }).count();
    }

Thread[main,5,main]::1
Thread[main,5,main]::4
Thread[main,5,main]::6
Thread[main,5,main]::7
Thread[main,5,main]::8
Thread[main,5,main]::9
Thread[main,5,main]::2
Thread[main,5,main]::3
Copy the code

Parallel Stream streams

public void testParallelStream(a){
       ArrayList<Object> list = new ArrayList<>();
       // Get the parallel stream directly
       Stream<Object> stream = list.parallelStream();
       // Turn a serial stream into a parallel stream
       Stream<Object> parallel = list.stream().parallel();

       Stream.of(1.4.6.7.8.9.2.3).parallel().filter(e->{
           System.out.println(Thread.currentThread()+"... ""+e);
           return e>3;
       }).count();
   }

Thread[ForkJoinPool.commonPool-worker-1.5,main]::6
Thread[ForkJoinPool.commonPool-worker-2.5,main]::4
Thread[ForkJoinPool.commonPool-worker-2.5,main]::3
Thread[ForkJoinPool.commonPool-worker-3.5,main]::7
Thread[ForkJoinPool.commonPool-worker-2.5,main]::2
Thread[ForkJoinPool.commonPool-worker-3.5,main]::8
Thread[ForkJoinPool.commonPool-worker-1.5,main]::1
Thread[main,5,main]::9
Copy the code

Resolve parallelStream thread safety issues

public void testParallelStreamNotice(a){
        List<Integer> list = new ArrayList<>();
        IntStream.rangeClosed(0.1000).parallel().forEach( e->{
            list.add(e);
        });
        System.out.println("list:"+list.size());
        ParallelStream (parallelStream) ¶
        Object obj = new Object();
        IntStream.rangeClosed(0.1000).parallel().forEach( e->{
            synchronized(obj){ list.add(e); }});// Use thread-safe collections
        //Vector<Integer> list2 = new Vector<>();
        Collection<Integer> synchronizedList = Collections.synchronizedCollection(list);
        IntStream.rangeClosed(0.1000).parallel().forEach( e->{
            synchronizedList.add(e);
        });
        Call stream collect/toArray
        List<Integer> collect = IntStream.rangeClosed(0.1000).parallel().boxed().collect(Collectors.toList());
    }
Copy the code