Java自学-Lambda 聚合操作

java 集合的聚合操作

步骤 1 : 传统方式与聚合操作方式遍历数据

遍历数据的传统方式就是使用for循环,然后条件判断,最后打印出满足条件的数据

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

  
  

使用聚合操作方式,画风就发生了变化:

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&lt;Hero&gt; heros = new ArrayList&lt;Hero&gt;();
    for (int i = 0; i &lt; 5; i++) {
        heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
    }

    System.out.println("初始化后的集合:");
    System.out.println(heros);
    System.out.println("查询条件:hp&gt;100 &amp;&amp; damage&lt;50");
    System.out.println("通过传统操作方式找出满足条件的数据:");

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

    System.out.println("通过聚合操作方式找出满足条件的数据:");
    heros
        .stream()
        .filter(h -&gt; h.hp &gt; 100 &amp;&amp; h.damage &lt; 50)
        .forEach(h -&gt; System.out.println(h.name));

}

}

步骤 2 : Stream和管道的概念

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

 
 

要了解聚合操作,首先要建立Stream管道的概念
Stream 和Collection结构化的数据不一样,Stream是一系列的元素,就像是生产线上的罐头一样,一串串的出来。
管道指的是一系列的聚合操作。

管道又分3个部分
管道源:在这个例子里,源是一个List
中间操作: 每个中间操作,又会返回一个Stream,比如.filter()又返回一个Stream, 中间操作是“懒”操作,并不会真正进行遍历。
结束操作:当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。 结束操作不会返回Stream,但是会返回int、float、String、 Collection或者像forEach,什么都不返回, 结束操作才进行真正的遍历行为,在遍历的时候,才会去进行中间操作的相关判断

: 这个Stream和I/O章节的InputStream,OutputStream是不一样的概念。

步骤 3 : 管道源

把Collection切换成管道源很简单,调用stream()就行了。

heros.stream()

 
 

但是数组却没有stream()方法,需要使用

Arrays.stream(hs)

 
 

或者

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&lt;Hero&gt; heros = new ArrayList&lt;Hero&gt;();
    for (int i = 0; i &lt; 5; i++) {
        heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
    }
    //管道源是集合
    heros
    .stream()
    .forEach(h-&gt;System.out.println(h.name));
     
    //管道源是数组
    Hero hs[] = heros.toArray(new Hero[heros.size()]);
    Arrays.stream(hs)
    .forEach(h-&gt;System.out.println(h.name));
     
}

}

步骤 4 : 中间操作

每个中间操作,又会返回一个Stream,比如.filter()又返回一个Stream, 中间操作是“懒”操作,并不会真正进行遍历。
中间操作比较多,主要分两类:
对元素进行筛选 和 转换为其他形式的流

对元素进行筛选:
filter 匹配
distinct 去除重复(根据equals判断)
sorted 自然排序
sorted(Comparator) 指定排序
limit 保留
skip 忽略

转换为其他形式的流:
mapToDouble 转换为double的流
map 转换为任意类型的流

中间操作

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;
}
//初始化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&lt;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&lt;Hero&gt; heros = new ArrayList&lt;Hero&gt;();
    for (int i = 0; i &lt; 5; i++) {
        heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
    }
    //制造一个重复数据
    heros.add(heros.get(0));
    System.out.println("初始化集合后的数据 (最后一个数据重复):");
    System.out.println(heros);
    System.out.println("满足条件hp&gt;100&amp;&amp;damage&lt;50的数据");
      
    heros
        .stream()
        .filter(h-&gt;h.hp&gt;100&amp;&amp;h.damage&lt;50)
        .forEach(h-&gt;System.out.print(h));
      
    System.out.println("去除重复的数据,去除标准是看equals");
    heros
        .stream()
        .distinct()
        .forEach(h-&gt;System.out.print(h));
    System.out.println("按照血量排序");
    heros
        .stream()
        .sorted((h1,h2)-&gt;h1.hp&gt;=h2.hp?1:-1)
        .forEach(h-&gt;System.out.print(h));
      
    System.out.println("保留3个");
    heros
        .stream()
        .limit(3)
        .forEach(h-&gt;System.out.print(h));
      
    System.out.println("忽略前3个");
    heros
        .stream()
        .skip(3)
        .forEach(h-&gt;System.out.print(h));
      
    System.out.println("转换为double的Stream");
    heros
        .stream()
        .mapToDouble(Hero::getHp)
        .forEach(h-&gt;System.out.println(h));
      
    System.out.println("转换任意类型的Stream");
    heros
        .stream()
        .map((h)-&gt; h.name + " - " + h.hp + " - " + h.damage)
        .forEach(h-&gt;System.out.println(h));
      
}

}

步骤 5 : 结束操作

当进行结束操作后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。 结束操作不会返回Stream,但是会返回int、float、String、 Collection或者像forEach,什么都不返回,。
结束操作才真正进行遍历行为,前面的中间操作也在这个时候,才真正的执行。

常见结束操作如下:

forEach() 遍历每个元素
toArray() 转换为数组
min(Comparator) 取最小的元素
max(Comparator) 取最大的元素
count() 总数
findFirst() 第一个元素

结束操作

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&lt;Hero&gt; heros = new ArrayList&lt;Hero&gt;();
    for (int i = 0; i &lt; 5; i++) {
        heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
    }
    System.out.println("遍历集合中的每个数据");
    heros
        .stream()
        .forEach(h-&gt;System.out.print(h));
    System.out.println("返回一个数组");
    Object[] hs= heros
        .stream()
        .toArray();
    System.out.println(Arrays.toString(hs));
    System.out.println("返回伤害最低的那个英雄");
    Hero minDamageHero =
    heros
        .stream()
        .min((h1,h2)-&gt;h1.damage-h2.damage)
        .get();
    System.out.print(minDamageHero);
    System.out.println("返回伤害最高的那个英雄");

    Hero mxnDamageHero =
            heros
            .stream()
            .max((h1,h2)-&gt;h1.damage-h2.damage)
            .get();
    System.out.print(mxnDamageHero);     
     
    System.out.println("流中数据的总数");
    long count = heros
            .stream()
            .count();
    System.out.println(count);

    System.out.println("第一个英雄");
    Hero firstHero =
            heros
            .stream()
            .findFirst()
            .get();
     
    System.out.println(firstHero);
     
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值