Collecting data using Stream

Posted by shorty3 on Fri, 28 Jan 2022 18:34:17 +0100

Tip: after the article is written, the directory can be generated automatically. Please refer to the help document on the right for how to generate it

preface

collect is a reduction operation. Just like reduce, it can accept various methods as parameters to accumulate the elements in the flow into a summary result. The specific method is defined by defining a new Collector interface.

1, Method of use

1. Statute and summary

public static void collectTest(){
        List<Integer> numbers = Arrays.asList(1,2,3,4,5);
        System.out.println(numbers.stream().count());//Number of elements
        Map<Boolean, List<Integer>> collect = numbers.stream().collect(groupingBy(i -> i % 2 == 0));//Group in odd and even numbers
        System.out.println(collect.get(true));
        System.out.println(numbers.stream().collect(maxBy(Comparator.comparingInt(i->i))));//Maximum
        System.out.println(numbers.stream().collect(summingInt(i->i)));//and
        System.out.println(numbers.stream().collect(summarizingInt(i->i)));//Once and for all, common summary data
        System.out.println(numbers.stream().map(i->i+"").collect(joining(",")));//Connect the string and set the separator
    }
5
[2, 4]
Optional[5]
15
IntSummaryStatistics{count=5, sum=15, min=1, average=3.000000, max=5}
1,2,3,4,5

2. Grouping

  1. Single level grouping

Group items in a collection by one attribute

Actual combat: group according to Dish's type

public class Dish {
    String type;
    String name;
    int costs;
}
public static void groupTest() {
        List<Dish> dishes=Arrays.asList(new Dish("fish","prawns",200),
                new Dish("fish","salmon",200),
                new Dish("meat","pock",20),
                new Dish("meat","beef",30),
                new Dish("meat","chicken",400),
                new Dish("other","rice",50),
                new Dish("other","fruit",60),
                new Dish("other","pizza",700));//Data array
        Map<String,List<Dish>> dishByType=
                dishes.stream().collect(Collectors.groupingBy(Dish::getType));//Group by category
        for(Map.Entry type : dishByType.entrySet()){
            String key=type.getKey().toString();
            System.out.print(key+":");
            List<Dish> dishes1=(List)type.getValue();
            dishes1.forEach(o-> System.out.print(o.getName()+" "));
            System.out.println();
        }//Traversal output
    }

Output results

other:rice fruit pizza 
fish:prawns salmon 
meat:pock beef chicken
  1. Multilevel grouping

The items in the set are grouped according to multiple attributes, and then grouped on the basis of grouping.

Actual combat: on the basis of grouping by type, group by cost

public enum Level { EXPENSIVE, NORMAL}//Enumeration to represent the hierarchy

Map<String,Map<Level,List<Dish> > > dishesByMuti=
                dishes.stream().collect(Collectors.groupingBy(Dish::getType,//Primary grouping
                        Collectors.groupingBy(o ->{//Secondary grouping
                            if(o.getCosts()>100) return Level.EXPENSIVE;
                            else return Level.NORMAL;
                        })));
        for(Map.Entry type : dishesByMuti.entrySet()){//ergodic
            String key=type.getKey().toString();
            System.out.print(key+": [");
            Map<Level,List<Dish>> typeList=(Map)type.getValue();
            for(Map.Entry level : typeList.entrySet()){
                String levelName=level.getKey().toString();
                List<Dish> list=(List) level.getValue();
                System.out.print(levelName+"[");
                list.forEach(o->{
                    System.out.print(o.getName()+":"+o.getCosts()+",");
                });
                System.out.print("]");
            }
            System.out.println(" ]");
        }

Output results

other: [ EXPENSIVE[pizza:700,]NORMAL[rice:50,fruit:60,] ]
fish: [ EXPENSIVE[prawns:200,salmon:200,] ]
meat: [ EXPENSIVE[chicken:400,]NORMAL[pock:20,beef:30,] ]

3. Zoning

Partition is a special case of grouping: a predicate (a function that returns a Boolean value) is used as the classification function, which is called partition function. The partition function returns a Boolean value, which means that the key type of the obtained grouping Map is Boolean, so it can be divided into two groups at most - true is one group and false is one group.

Actual combat: group according to whether the dishes are cheap or not

public static Boolean isCheap(Dish dish){
        return dish.getCosts()<50;
}
Map<Boolean,List<Dish>> cheapMap=
                dishes.stream().collect(Collectors.partitioningBy(Dish::isCheap));
        for(Map.Entry type : cheapMap.entrySet()){
            String key=type.getKey().toString();
            System.out.print(key+":[ ");
            List<Dish> dishes1=(List)type.getValue();
            dishes1.forEach(o-> System.out.print(o.getName()+":"+o.getCosts()+","));
            System.out.println(" ]");
        }

Output results

false:[ prawns:200,salmon:200,chicken:400,rice:50,fruit:60,pizza:700, ]
true:[ pock:20,beef:30, ]

In fact, you can also query twice through the filter

//Cheap collection, not cheap similar
 Map<Boolean,List<Dish>> cheapMap=
                dishes.stream().collect(Collectors.partitioningBy(Dish::isCheap));
        List<Dish> cheapMap2=
                dishes.stream().filter(Dish::isCheap).collect(toList());
        cheapMap2.forEach(o->{
            System.out.print(o.getName()+",");
        });
pock
beef

In fact, both partitioning and deletion can meet the change requirements, but the advantage of partitioning is that it retains the two sets of flow element lists that the partition function returns true or false.

summary

Tip: here is a summary of the article:
For example, the above is what we want to talk about today. This paper only briefly introduces the use of pandas, which provides a large number of functions and methods that enable us to process data quickly and conveniently.