函数式编程、Lambda 表达式、Stream API

1.引入:函数式接口->函数式编程->Lambda(匿名内部类->匿名方法)->Stream
2.方法引用
3.Lambda聚合操作,类似于spark的RDD算子
    1.中间操作->转换算子
        对元素进行筛选:
            filter 匹配
            distinct 去除重复(根据equals判断)
            sorted 自然排序
            sorted(Comparator<T>) 指定排序
            limit 保留
            skip 忽略
        转换为其他形式的流
            mapToDouble 转换为double的流
            map 转换为任意类型的流
            flatMap
    2.结束操作->行为算子
        常见结束操作如下:
            forEach() 遍历每个元素
            toArray() 转换为数组
            min(Comparator<T>) 取最小的元素
            max(Comparator<T>) 取最大的元素
            count() 总数
            findFirst() 第一个元素
            reduce:累加,其用作从一个流中生成一个值
    3.Java8四大内置函数式接口
参考:https://how2j.cn/k/lambda/lambda-lamdba-tutorials/697.html
https://blog.youkuaiyun.com/zxzxzx0119/article/details/82392396
算子:https://www.runoob.com/java/java8-streams.html


示例:
1.reduce:https://www.jdon.com/56432
    Java Stream对List<Map>类数据求和:BigDecimal sum = list.stream().map(x -> new BigDecimal(String.valueOf(x.get("score")))).reduce(BigDecimal.ZERO,BigDecimal::add);

    List<Integer> arrayList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
    /**
     * 求和
     */
    Integer sum = arrayList.stream().reduce(Integer::sum).orElse(0);
    System.out.println(sum); // 45
    /**
     * 求最大值
     */
    Integer max = arrayList.stream().reduce(Integer::max).orElse(0);
    System.out.println(max); // 9

    /**
     * 求最小值
     */
    Integer min = arrayList.stream().reduce(Integer::min).orElse(0);
    System.out.println(min); // 1
    // 或者
    IntSummaryStatistics stats = arrayList.stream().mapToInt((x) ->x).summaryStatistics();
    stats.getMin();
    stats.getMax();
    stats.getCount();
    stats.getSum();
    stats.getAverage();
2.collect
    List<Map<String, Object>> appoinimentData = workArrangeMapper.getAppointmentPanel(date,doctor);
    appoinimentData = appoinimentData.parallelStream().map(e -> {
        if(e.get("title").toString().endsWith(",")) {
            e.put("title", e.get("title").toString().substring(0, e.get("title").toString().length()-1));
        }
        return e;
    }).collect(Collectors.toList());
3.map和flatMap的区别
// 1.先看看这两有啥不同
List<String[]> result5 = Stream.of("guang").map(e->e.split("")).collect(Collectors.toList());
System.out.println(JSON.toJSONString(result5)); // [["g","u","a","n","g"]]

List<String> result6 = Stream.of("guang").flatMap(e->Arrays.stream(e.split(""))).collect(Collectors.toList());
System.out.println(JSON.toJSONString(result6)); // ["g","u","a","n","g"]

// 2.拆分,需求给定单词列表["Hello","World"],你想要返回列表["H","e","l", "o","W","r","d"],
List<String> ddd = new ArrayList();
ddd.add("abcd");
ddd.add("tianming");
ddd.add("abcd");
String[] strings = {"abcd", "tianming", "abcd"};

List<String[]> result1 = ddd.stream().map(e->e.split("")).distinct().collect(Collectors.toList());
System.out.println(JSON.toJSONString(result1)); // [["a","b","c","d"],["t","i","a","n","m","i","n","g"],["a","b","c","d"]]

List<String[]> result2 = Stream.of(strings).map(e->e.split("")).distinct().collect(Collectors.toList());
System.out.println(JSON.toJSONString(result2)); // [["a","b","c","d"],["t","i","a","n","m","i","n","g"],["a","b","c","d"]]

List<String> result3 = ddd.stream().flatMap(str -> Arrays.stream(str.split(""))).distinct().collect(Collectors.toList());
System.out.println(JSON.toJSONString(result3)); // ["a","b","c","d","t","i","n","m","g"]

List<String> result4 = Stream.of(strings).flatMap(str -> Arrays.stream(str.split(""))).distinct().collect(Collectors.toList());
System.out.println(JSON.toJSONString(result4)); // ["a","b","c","d","t","i","n","m","g"]

// 3.合并,获取所有英雄的所有装备
import java.util.Comparator;
import java.util.List;

public class Hero implements Comparable<Hero>{
    public String name;
    public float hp;
    public int damage;
    public List<String> arms; // 装备
        
    public Hero(){
    }
       
    public Hero(String name) {
        this.name =name;
    }
       
    //初始化name,hp,damage的构造方法
    public Hero(String name,float hp, int damage,List<String> arms) {
        this.name =name;
        this.hp = hp;
        this.damage = damage;
        this.arms = arms;
    }
   
    @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";
    }
       
}
测试:
Hero hero1 = new Hero("小提莫",80,240,CollUtil.newArrayList("多兰戒","痛苦面具"));
Hero hero2 = new Hero("德玛",90,200,CollUtil.newArrayList("多蓝盾","挺进破坏者"));
Hero hero3 = new Hero("熔岩巨兽",75,300,CollUtil.newArrayList("大药水","钢之心"));
ArrayList<Hero> heros = CollUtil.newArrayList(hero1, hero2, hero3);
List<String> resultList = new ArrayList<>();
for (Hero hero : heros) {
    resultList.addAll(hero.arms);
}
System.out.println(JSON.toJSONString(resultList)); // 勉强 ["多兰戒","痛苦面具","多蓝盾","挺进破坏者","大药水","钢之心"]
List<List<String>> resultList2 = heros.stream().map(e->e.arms).collect(Collectors.toList());
System.out.println(JSON.toJSONString(resultList2)); // 不行 [["多兰戒","痛苦面具"],["多蓝盾","挺进破坏者"],["大药水","钢之心"]]
List<String> resultList3 = heros.stream().flatMap(e->e.arms.stream()).collect(Collectors.toList());
System.out.println(JSON.toJSONString(resultList3)); // yyds ["多兰戒","痛苦面具","多蓝盾","挺进破坏者","大药水","钢之心"]


总结:map和flatMap的区别(和spark的RDD中的map和flatMap是一样的)
1.共同点
都是依赖FuncX(入参,返回值)进行转换(将一个类型依据程序逻辑转换成另一种类型,根据入参和返回值)
都能在转换后直接被subscribe
2.不同点
map是将集合中的元素进行格式上的统一转换,数量不会发生变化
flatMap是将集合中的元素进行拆分或者合并,数量会发生变化
另:Arrays.stream()将数组转换为stream

4.Collectors
Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串:

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("筛选列表: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值