Java函数式编程Lambda表达式(函数式接口、Optional、Stream流)


GitHub: link. 欢迎star

注意:本篇博客风格(不多比比就是撸代码!!!)

一、函数式接口

1.说明

a.接口中只有一个抽象方法
b.写匿名内部类的时候,可以转换成lambda表达式

2.接口

/**
 * @author Andon
 * 2022/2/10
 * <p>
 * 函数式接口
 * <p>
 * 接口中只有一个抽象方法
 * 写匿名内部类的时候,可以转换成lambda表达式
 */
@FunctionalInterface
public interface MyFunction<T, R> {

    /**
     * 唯一一个抽象方法
     */
    R myApply(T t);

    /**
     * 默认方法
     */
    default void test() {
    }
}

3.测试

import com.andon.springbootutil.service.MyFunction;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

/**
 * @author Andon
 * 2022/2/10
 * <p>
 * 函数式编程测试类
 */
@Slf4j
public class FunctionalCodeTest {

    /**
     * 函数式接口测试
     */
    @Test
    public void functionalInterfaceTest() {
        String string = "128";
        Integer function = sting2Integer.myApply(string);
        log.info("function >>> {} type:{}", function, function.getClass().getName());
    }

    // 重写函数式接口的唯一抽象方法:将一个字符串转换成Integer
    private MyFunction<String, Integer> sting2Integer = s -> {
        log.info("type:{}", s.getClass().getName());
        return Integer.valueOf(s);
    };
}

二、Optional

1.说明

  • 创建对象:ofNullable() empty()
  • 消费值:ifPresent()
  • 获取值:orElseGet() orElseThrow()
  • 过滤:filter()
  • 判断:isPresent()
  • 数据转换:map()

2.测试

import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.Optional;

/**
 * @author Andon
 * 2022/2/10
 * <p>
 * 函数式编程测试类
 */
@Slf4j
public class FunctionalCodeTest {

    /**
     * Optional
     * <p>
     * 创建对象:ofNullable() empty()
     * 消费值:ifPresent()
     * 获取值:orElseGet() orElseThrow()
     * 过滤:filter()
     * 判断:isPresent()
     * 数据转换:map()
     */
    @Test
    public void optionalTest() {
        Hero hero = Hero.builder().name("name~~").build();
        System.out.println("=====Optional创建对象=====");
        Optional<Hero> heroOptional = Optional.ofNullable(hero);
        System.out.println("=====Optional消费值ifPresent=====");
        heroOptional.ifPresent(hero1 -> log.info("ifPresent.name:{}", hero1.name));
        System.out.println("=====Optional获取值orElseGet=====");
        heroOptional = Optional.empty();
        hero = heroOptional.orElseGet(() -> Hero.builder().name("name~~").build());
        log.info("orElseGet.name:{}", hero.name);
        System.out.println("=====Optional获取值抛异常orElseThrow=====");
        heroOptional = Optional.empty();
        //hero = heroOptional.orElseThrow(() -> new RuntimeException("数据为null"));
        System.out.println("=====Optional过滤filter=====");
        hero = Hero.builder().name("name~~").build();
        heroOptional = Optional.ofNullable(hero);
        heroOptional = heroOptional.filter(hero12 -> hero12.professional != null);
        heroOptional.ifPresent(hero1 -> log.info("ifPresent.name:{}", hero1.name));
        System.out.println("=====Optional判断isPresent=====");
        hero = Hero.builder().name("name~~").build();
        heroOptional = Optional.ofNullable(hero);
        if (heroOptional.isPresent()) {
            hero = heroOptional.get();
            log.info("isPresent.name:{}", hero.name);
        }
        System.out.println("=====Optional数据转换map=====");
        hero = Hero.builder().name("name~~").build();
        heroOptional = Optional.ofNullable(hero);
        Optional<String> nameOptional = heroOptional.map(hero1 -> hero1.name);
        nameOptional.ifPresent(s -> log.info("map.ifPresent.name:{}", s));
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @EqualsAndHashCode
    static class Hero {
        private String name;
        private String professional;
        private String roadName;
        private Integer road;
    }
}

三、Stream流

1.说明

  • 创建流-中间操作-终结操作
  • 创建流:stream()
  • 中间操作:filter() map() flatMap() distinct() sorted() limit() skip()
  • 终结操作:forEach() count() max() collect() anyMatch() allMatch() noneMatch() findAny() findFirst() reduce()
  • 创建并行流:stream().parallel()或者parallelStream()
  • 调试:peek()

2.串行流

import com.alibaba.fastjson.JSONObject;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Andon
 * 2022/2/10
 * <p>
 * 函数式编程测试类
 */
@Slf4j
public class FunctionalCodeTest {

    /**
     * Stream
     * 创建流-中间操作-终结操作
     * <p>
     * 创建流:stream()
     * 中间操作:filter() map() flatMap() distinct() sorted() limit() skip()
     * 终结操作:forEach() count() max() collect() anyMatch() allMatch() noneMatch() findAny() findFirst() reduce()
     */
    @Test
    public void streamTest() {
        List<Hero> heroList = getHeroes();
        log.info("heroList.size={}", heroList.size());
        System.out.println("filter,forEach=====打印所有刺客名字=====");
        heroList.stream()
                .filter(h -> h.road == 4)
                .forEach(hero -> log.info("professional:{} name:{}", hero.professional, hero.name));
        System.out.println("filter,forEach=====打印所有射手名字=====");
        Hero[] heroArr = heroList.toArray(new Hero[0]);
        Stream<Hero> heroArrStream = Arrays.stream(heroArr);
        heroArrStream
                .filter(hero -> hero.road == 3)
                .forEach(hero -> log.info("professional:{} name:{}", hero.professional, hero.name));
        System.out.println("filter,forEach=====打印所有英雄名字是大于两个字的英雄名字=====");
        heroList.stream()
                .filter(hero -> hero.name.length() > 2)
                .forEach(hero -> log.info("hero.name:{}", hero.name));
        System.out.println("map=====打印所有英雄名字=====");
        heroList.stream()
                .map(Hero::getName)
                .forEach(name -> log.info("name:{}", name));
        System.out.println("distinct=====打印所有的刺客名字(去重)=====");
        heroList.stream()
                .filter(h -> h.road == 4)
                .distinct()
                .forEach(hero -> log.info("hero:{}", JSONObject.toJSONString(hero)));
        System.out.println("sorted=====打印所有英雄名字是大于两个字的英雄名字(去重),根据路倒叙进行排序=====");
        heroList.stream()
                .distinct()
                .filter(hero -> hero.name.length() > 2)
                .sorted((o1, o2) -> o2.road - o1.road)
                .forEach(hero -> log.info("hero:{}", JSONObject.toJSONString(hero)));
        System.out.println("limit=====去重,路倒叙,打印路最大的两位英雄=====");
        heroList.stream()
                .distinct()
                .sorted((o1, o2) -> o2.road - o1.road)
                .limit(2)
                .forEach(hero -> log.info("hero:{}", JSONObject.toJSONString(hero)));
        System.out.println("skip=====去重,路倒叙,打印除了路最大的两位英雄=====");
        heroList.stream()
                .distinct()
                .sorted((o1, o2) -> o2.road - o1.road)
                .limit(5)
                .skip(2)
                .forEach(hero -> log.info("hero:{}", JSONObject.toJSONString(hero)));
        System.out.println("=====打印所有的职业(去重)=====");
        heroList.stream()
                .map(hero -> hero.professional)
                .distinct()
                .forEach(name -> log.info("name:{}", name));
        System.out.println("flatMap=====打印所有的路名字(去重)=====");
        heroList.stream()
                .flatMap(hero -> Arrays.stream(hero.roadName.split(",")))
                .distinct()
                .forEach(name -> log.info("name:{}", name));
        System.out.println("count=====所有刺客的英雄名字(去重)个数=====");
        long countCiKe = heroList.stream()
                .filter(hero -> hero.professional.equals("刺客"))
                .map(hero -> hero.name)
                .distinct()
                .count();
        log.info("countCiKe:{}", countCiKe);
        System.out.println("max=====所有刺客中路最大的英雄名字=====");
        Optional<Integer> max = heroList.stream()
                .map(hero -> hero.road)
                .max((o1, o2) -> o1 - o2);
        max.ifPresent(integer -> log.info("integer:{}", integer));
        System.out.println("collect=====获取所有刺客名字的List集合=====");
        List<String> ciKeList = heroList.stream()
                .filter(hero -> hero.professional.equals("刺客"))
                .map(hero -> hero.name)
                .distinct()
                .collect(Collectors.toList());
        log.info("ciKeList:{}", JSONObject.toJSONString(ciKeList));
        System.out.println("collect=====获取所有刺客名字的Set集合=====");
        Set<String> ciKeSet = heroList.stream()
                .filter(hero -> hero.professional.equals("刺客"))
                .map(hero -> hero.name)
                .collect(Collectors.toSet());
        log.info("ciKeSet:{}", JSONObject.toJSONString(ciKeSet));
        System.out.println("collect=====获取一个Map,刺客英雄名字:职业=====");
        Map<String, String> map = heroList.stream()
                .filter(hero -> hero.professional.equals("刺客"))
                .distinct()
                .collect(Collectors.toMap(hero -> hero.name, hero -> hero.professional));
        log.info("map:{}", JSONObject.toJSONString(map));
        System.out.println("anyMatch=====判断是否有名字是4个字的刺客=====");
        boolean anyMatch = heroList.stream()
                .filter(hero -> hero.professional.equals("刺客"))
                .anyMatch(hero -> hero.name.length() == 4);
        log.info("anyMatch:{}", anyMatch);
        System.out.println("allMatch=====判断是否法师的所有名字都是大于2个字的=====");
        boolean allMatch = heroList.stream()
                .filter(hero -> hero.professional.equals("法师"))
                .allMatch(hero -> hero.name.length() >= 2);
        log.info("allMatch:{}", allMatch);
        System.out.println("noneMatch=====判断是否所有刺客的名字都是小于4个字的=====");
        boolean noneMatch = heroList.stream()
                .filter(hero -> hero.professional.equals("刺客"))
                .noneMatch(hero -> hero.name.length() >= 4);
        log.info("noneMatch:{}", noneMatch);
        System.out.println("findAny=====获取任意一个名字是1个字的刺客=====");
        Optional<Hero> anyOptional = heroList.stream()
                .filter(hero -> hero.professional.equals("刺客"))
                .filter(hero -> hero.name.length() == 1)
                .findAny();
        anyOptional.ifPresent(hero -> log.info("hero:{}", JSONObject.toJSONString(hero)));
        System.out.println("findFirst=====获取第一个名字是3个字的刺客=====");
        Optional<Hero> firstOptional = heroList.stream()
                .filter(hero -> hero.professional.equals("刺客"))
                .filter(hero -> hero.name.length() == 3)
                .findFirst();
        firstOptional.ifPresent(hero -> log.info("hero:{}", JSONObject.toJSONString(hero)));
        System.out.println("reduce=====所有刺客的名字连接在一起=====");
        Optional<String> reduceOptional = heroList.stream()
                .filter(hero -> hero.professional.equals("刺客"))
                .distinct()
                .map(hero -> hero.name)
                .reduce((s, s2) -> s + " " + s2);
        reduceOptional.ifPresent(s -> log.info("name:{}", s));
        System.out.println("reduce=====获取刺客中名字最短的名字=====");
        Optional<String> reduceNameOptional = heroList.stream()
                .filter(hero -> hero.professional.equals("刺客"))
                .distinct()
                .map(hero -> hero.name)
                .reduce((s, s2) -> s.length() < s2.length() ? s : s2);
        reduceNameOptional.ifPresent(s -> log.info("name:{}", s));
    }

    private List<Hero> getHeroes() {
        List<Hero> heroes = new ArrayList<>();
        heroes.add(Hero.builder().name("花木兰").professional("战士").roadName("边路").road(1).build());
        heroes.add(Hero.builder().name("吕布").professional("战士").roadName("边路").road(1).build());
        heroes.add(Hero.builder().name("曹操").professional("战士").roadName("边路").road(1).build());
        heroes.add(Hero.builder().name("杨戬").professional("战士").roadName("边路").road(1).build());
        heroes.add(Hero.builder().name("老夫子").professional("战士").roadName("边路").road(1).build());
        heroes.add(Hero.builder().name("妲己").professional("法师").roadName("中路").road(2).build());
        heroes.add(Hero.builder().name("安琪拉").professional("法师").roadName("中路").road(2).build());
        heroes.add(Hero.builder().name("小乔").professional("法师").roadName("中路").road(2).build());
        heroes.add(Hero.builder().name("甄姬").professional("法师").roadName("中路").road(2).build());
        heroes.add(Hero.builder().name("貂蝉").professional("法师").roadName("中路").road(2).build());
        heroes.add(Hero.builder().name("婉儿").professional("法师").roadName("中路").road(2).build());
        heroes.add(Hero.builder().name("金蝉").professional("法师").roadName("中路").road(2).build());
        heroes.add(Hero.builder().name("马可").professional("射手").roadName("下路").road(3).build());
        heroes.add(Hero.builder().name("虞姬").professional("射手").roadName("下路").road(3).build());
        heroes.add(Hero.builder().name("香香").professional("射手").roadName("下路").road(3).build());
        heroes.add(Hero.builder().name("鲁班").professional("射手").roadName("下路").road(3).build());
        heroes.add(Hero.builder().name("李元芳").professional("射手").roadName("下路").road(3).build());
        heroes.add(Hero.builder().name("赵云").professional("刺客").roadName("打野").road(4).build());
        heroes.add(Hero.builder().name("赵云").professional("刺客").roadName("打野").road(4).build());
        heroes.add(Hero.builder().name("司马懿").professional("刺客").roadName("打野").road(4).build());
        heroes.add(Hero.builder().name("司马懿").professional("刺客").roadName("打野").road(4).build());
        heroes.add(Hero.builder().name("司马懿").professional("刺客").roadName("打野").road(4).build());
        heroes.add(Hero.builder().name("兰陵王").professional("刺客").roadName("打野").road(4).build());
        heroes.add(Hero.builder().name("鸟人").professional("刺客").roadName("打野").road(4).build());
        heroes.add(Hero.builder().name("澜").professional("刺客").roadName("打野").road(4).build());
        return heroes;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @EqualsAndHashCode
    static class Hero {
        private String name;
        private String professional;
        private String roadName;
        private Integer road;
    }
}

3.并行流

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author Andon
 * 2022/2/10
 * <p>
 * 函数式编程测试类
 */
@Slf4j
public class FunctionalCodeTest {

    /**
     * Stream并行流
     * <p>
     * 创建并行流:stream().parallel()或者parallelStream()
     * 调试:peek()
     */
    @Test
    public void parallelStreamTest() {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(i);
        }
        //Optional<Integer> reduce = list.parallelStream()
        Optional<Integer> reduce = list.stream()
                .parallel()
                .peek(integer -> log.info("Thread:[{}] >>> {}", Thread.currentThread().getName(), integer))
                .filter(integer -> integer >= 5)
                .reduce(Integer::sum);
        reduce.ifPresent(integer -> log.info("reduce:{}", integer));
    }
}

GitHub: link. 欢迎star

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值