Java self study Lambda aggregation operation

Keywords: Java Lambda

Aggregation operation of java collection

Step 1: traverse data in the traditional way and aggregate operation way

The traditional way of traversing data is to use the for loop, then judge the conditions, and finally print out the data that meets the conditions

for (Hero h : heros) {
   if (h.hp > 100 && h.damage < 50)
      System.out.println(h.name);
}

With aggregation, the style of painting changes:

heros
    .stream()
    .filter(h -> h.hp > 100 && h.damage < 50)
    .forEach(h -> System.out.println(h.name));

package lambda;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
 
import charactor.Hero;
 
public class TestAggregate {
 
    public static void main(String[] args) {
        Random r = new Random();
        List<Hero> heros = new ArrayList<Hero>();
        for (int i = 0; i < 5; i++) {
            heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
        }
 
        System.out.println("Initialized collection:");
        System.out.println(heros);
        System.out.println("Query criteria: hp>100 && damage<50");
        System.out.println("Find the data that meets the conditions through traditional operation mode:");
 
        for (Hero h : heros) {
            if (h.hp > 100 && h.damage < 50)
                System.out.println(h.name);
        }
 
        System.out.println("Find the data that meets the conditions through aggregation operation:");
        heros
            .stream()
            .filter(h -> h.hp > 100 && h.damage < 50)
            .forEach(h -> System.out.println(h.name));
 
    }
}

Step 2: the concept of stream and pipeline

heros
    .stream()
    .filter(h -> h.hp > 100 && h.damage < 50)
    .forEach(h -> System.out.println(h.name));

To understand aggregation operations, first establish the concept of Stream and pipeline
Stream is different from the structured data of Collection. Stream is a series of elements, just like a can on a production line, coming out in series.
Pipeline refers to a series of aggregation operations.

The pipeline is divided into three parts
Pipe source: in this case, the source is a List
Intermediate operation: each intermediate operation will return another Stream, for example. filter() will return another Stream. The intermediate operation is lazy and will not be traversed.
End operation: when this operation is executed, the Stream will be used with "light" and can no longer be operated. So this must be the last operation of the flow. The end operation will not return Stream, but it will return int, float, String, Collection or anything like forEach. Only when the end operation is finished can the real traversal be carried out, and only when the traversal is carried out can the related judgment of the intermediate operation be carried out

Note: this Stream is different from the InputStream and OutputStream in the I/O chapter.

Step 3: pipe source

It's easy to switch the Collection to a pipe source, just call stream().

heros.stream()

However, there is no stream() method for arrays, so you need to use

Arrays.stream(hs)

perhaps

Stream.of(hs)

.

package lambda;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
 
import charactor.Hero;
 
public class TestAggregate {
 
    public static void main(String[] args) {
        Random r = new Random();
        List<Hero> heros = new ArrayList<Hero>();
        for (int i = 0; i < 5; i++) {
            heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
        }
        //The source is the assembly
        heros
        .stream()
        .forEach(h->System.out.println(h.name));
         
        //The source is an array
        Hero hs[] = heros.toArray(new Hero[heros.size()]);
        Arrays.stream(hs)
        .forEach(h->System.out.println(h.name));
         
    }
}

Step 4: intermediate operation

Each intermediate operation will return another Stream, for example. filter() will return another Stream. The intermediate operation is "lazy" and will not be traversed.
There are many intermediate operations, mainly divided into two categories:
Filtering and converting elements to other forms of flow

Filter elements:
filter matching
distinct to remove duplicates (based on equals)
sorted natural sorting
sorted(Comparator) specifies sorting
limit reservation
skip ignores

Convert to other forms of flow:
mapToDouble to double flow
map to any type of stream

package charactor;
      
public class Hero implements Comparable<Hero>{
    public String name;
    public float hp;
         
    public int damage;
         
    public Hero(){
            
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getHp() {
        return hp;
    }
    public void setHp(float hp) {
        this.hp = hp;
    }
    public int getDamage() {
        return damage;
    }
    public void setDamage(int damage) {
        this.damage = damage;
    }
    public Hero(String name) {
        this.name =name;
    }
    //The construction method of initializing name,hp,damage
    public Hero(String name,float hp, int damage) {
        this.name =name;
        this.hp = hp;
        this.damage = damage;
    }
    
    @Override
    public int compareTo(Hero anotherHero) {
        if(damage<anotherHero.damage)
            return 1; 
        else
            return -1;
    }
    
    @Override
    public String toString() {
        return "Hero [name=" + name + ", hp=" + hp + ", damage=" + damage + "]\r\n";
    }
        
}
package lambda;
  
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
 
import charactor.Hero;
  
public class TestAggregate {
  
    public static void main(String[] args) {
        Random r = new Random();
        List<Hero> heros = new ArrayList<Hero>();
        for (int i = 0; i < 5; i++) {
            heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
        }
        //Create a duplicate data
        heros.add(heros.get(0));
        System.out.println("Data after collection initialization (Last data repeat): ");
        System.out.println(heros);
        System.out.println("Meeting conditions hp>100&&damage<50 Data");
          
        heros
            .stream()
            .filter(h->h.hp>100&&h.damage<50)
            .forEach(h->System.out.print(h));
          
        System.out.println("To remove duplicate data, the standard is to equals");
        heros
            .stream()
            .distinct()
            .forEach(h->System.out.print(h));
        System.out.println("Sort by blood volume");
        heros
            .stream()
            .sorted((h1,h2)->h1.hp>=h2.hp?1:-1)
            .forEach(h->System.out.print(h));
          
        System.out.println("Keep 3.");
        heros
            .stream()
            .limit(3)
            .forEach(h->System.out.print(h));
          
        System.out.println("Ignore the first three");
        heros
            .stream()
            .skip(3)
            .forEach(h->System.out.print(h));
          
        System.out.println("Convert to double Of Stream");
        heros
            .stream()
            .mapToDouble(Hero::getHp)
            .forEach(h->System.out.println(h));
          
        System.out.println("Convert any type of Stream");
        heros
            .stream()
            .map((h)-> h.name + " - " + h.hp + " - " + h.damage)
            .forEach(h->System.out.println(h));
          
    }
}

Step 5: end the operation

When the end operation is performed, the Stream is "light" and cannot be operated any more. So this must be the last operation of the flow. The end operation will not return Stream, but it will return int, float, String, Collection or anything like forEach,.
Only when the end operation is finished can the traversal behavior be carried out. The previous intermediate operation is also carried out at this time.

Common ending operations are as follows:

forEach() traverses each element
toArray() to array
min(Comparator) takes the smallest element
max(Comparator) takes the largest element
count() total
findFirst() first element

package lambda;
  
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
 
import org.omg.Messaging.SYNC_WITH_TRANSPORT;
 
import charactor.Hero;
  
public class TestAggregate {
  
    public static void main(String[] args) {
        Random r = new Random();
        List<Hero> heros = new ArrayList<Hero>();
        for (int i = 0; i < 5; i++) {
            heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
        }
        System.out.println("Traverse each data in the collection");
        heros
            .stream()
            .forEach(h->System.out.print(h));
        System.out.println("Returns an array");
        Object[] hs= heros
            .stream()
            .toArray();
        System.out.println(Arrays.toString(hs));
        System.out.println("Return to the hero with the lowest damage");
        Hero minDamageHero =
        heros
            .stream()
            .min((h1,h2)->h1.damage-h2.damage)
            .get();
        System.out.print(minDamageHero);
        System.out.println("Return to the hero with the highest damage");
 
        Hero mxnDamageHero =
                heros
                .stream()
                .max((h1,h2)->h1.damage-h2.damage)
                .get();
        System.out.print(mxnDamageHero);     
         
        System.out.println("Total number of data in the stream");
        long count = heros
                .stream()
                .count();
        System.out.println(count);
 
        System.out.println("First hero");
        Hero firstHero =
                heros
                .stream()
                .findFirst()
                .get();
         
        System.out.println(firstHero);
         
    }
}

Practice: Aggregation operation

The first choice is to prepare 10 Hero objects, hp and damage are random numbers.
Print out hp's third highest hero name in the traditional way and in the aggregate way

Answer:

package lambda;
  
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
 
import charactor.Hero;
  
public class TestAggregate {
  
    public static void main(String[] args) {
        Random r = new Random();
        List<Hero> heros = new ArrayList<Hero>();
        for (int i = 0; i < 10; i++) {
            heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
        }
 
        System.out.println("Data after collection initialization (Last data repeat): ");
        System.out.println(heros);
         
        //Traditional way
        Collections.sort(heros,new Comparator<Hero>() {
            @Override
            public int compare(Hero o1, Hero o2) {
                return (int) (o2.hp-o1.hp);
            }
        });
         
        Hero hero = heros.get(2);
        System.out.println("It's found in the traditional way hp The third highest hero name is:" + hero.name);
         
        //Polymerization mode
        String name =heros
            .stream()
            .sorted((h1,h2)->h1.hp>h2.hp?-1:1)
            .skip(2)
            .map(h->h.getName())
            .findFirst()
            .get();
 
        System.out.println("Found by aggregation hp The third highest hero name is:" + name);
         
    }
}

Posted by rtsanderson on Sat, 22 Feb 2020 21:09:11 -0800