函数编程 JAVA8 @FunctionalInterface

@FunctionalInterface

  • @FunctionalInterface 不是强制性的,
  • 优点1:使接口的含义更加明确
  • 优点2:编译器进行代码检查,保证没有预发错误。
  • 特点: 有且仅有一个默认的待实现方法(默认的方法 并不是使用default关键字修饰的方法)。
  • 注意点:默认方法 VS 默认实现的方法

JAVA为什么引入函数式编程

  • 减少了可变量(immutable variable)的声明
  • 可以更好的利用并行(parallelism)
  • 同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程
  • 代码更加简洁 可读性更高

Stream 与 MapReduce 思想上有什么关系

reduce 与 reduce() 有什么区别

@FunctionalInterface的默认函数 与 default关键字的含义有什么区别?

@FunctionalInterface
public interface Function<T, R> {

	    /**
	     * Applies this function to the given argument.
	     *
	     * @param t the function argument
	     * @return the function result
	     */
	     // 默认方法
	    R apply(T t);
	
		// 默认实现的方法
	    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
	        Objects.requireNonNull(before);
	        return (V v) -> apply(before.apply(v));
	    }
    }

常用的函数式编程有哪些?

接口默认方法符号描述含义特化
Predicate< T >boolean test(T t)T -> boolean谓词性接口,一般用于判断IntPredicate ; LongPredicate ; DoublePredicate
Function<T, R>R apply(T t);T->R功能型接口,它的一个作用就是转换作用
Consumer< T >void accept(T t);T->void传入一个类型值,没有返回值,端子函数使用较多IntConsumer,LongConsumer DoubleConsumer
SupplierT get();()->T当一个容器或者变量,可以存储值BooleanSupplier,IntSupplier LongSupplier
  • Function
  • Predicate
  • Consumer
  • Supplier
  • Runnable
  • Callable
  • Comparable

lambda表达式
lambda表达式 其实是一个匿名函数,他是一段没有函数名的函数体
lambda的基本写法是 (params) -> {body}
特点:

  • lambda 可以有0个 或 多个参数
  • lambda的参数类型可以明确声明,也可以通过上下文推断出参数类型
    eg: (int a) 与 (a) 含义是一致的
  • 全部参数都包含在 “()” 圆括号内,多个参数使用逗号分隔,仅有一个参数时"()" 圆括号可以省略
  • “() -> {sout(“1231”)}” 说明参数为空
  • 若body仅有一条语句时,“{}” 大括号可以省略
 (param1,param2) -> {dody}
 (type1 param1, type2 param2) -> {dody}
 eg:
 // 有返回值 函数
 (int a, int b)  -> {return a + b }
 () -> {sout("12567890")}
 // 无返回函数
 (String s) -> {sout(s)};
 // 无参函数,
 ()-> 42  
 

为什么Lambda表达式的函数体内 必须使用final关键字或实际上是final的变量

Stream 流的常见生产方式

  • Collection 体系的集合可以使用 xx.stream()的方式生成Stream对象
  • 数组可以可以使用 Stream.of(T … values) 生成Stream对象
  • Arrays.stream(T[] array)
  •  eg: Arrays.stream(values()).filter...
    

** 抽象类与接口的区别 **

  • 抽象类单继承 接口多实现
  • 抽象类 有构造函数、有实例属性 、有实例方法、 可以保存状态(state) ; 接口均没有
  • lambda 抽象类不能在lambda中使用
  • 思想上不同 is-a has-a like-a --忘记了类图的线的含义
  • is-a 继承关系, 小孩子都是人 类图表示为 实线 空心三角形
  • has-a 标识聚合关系 汽车由发送机 电机 底牌 聚合而成。
  • like-a 表示组合关系 虚线 空心三角形
/**
 * 学习使用java8 function
 */
@Slf4j
public class TestFunction {

    public static void main(String[] args) {

//        testConsumer();
        testSupplier();


    }

    /**
     * 学习使用Supplier , 返回一个字符串
     * <p>
     *     public void ifPresent(Consumer<? super T> consumer)
     * </p>
     */
    public static void testSupplier(){

        // 方式1 lambda方式
        Supplier<String> stringSupplier = () -> UUID.randomUUID().toString().replaceAll("-", "");
        log.info("学习使用Supplier lambda result:[{}]",stringSupplier.get());

        // 方式1 如果仅一步可以生成supplier 可以通过方法应用的方式创建 supplier
        Supplier<UUID> randomUUID = UUID::randomUUID;
        log.info("学习使用Supplier lambda result:[{}]",randomUUID.get().toString().replaceAll("-", ""));



        //方式2 接口实现的方式实现
        Supplier<String> supplier2 = new Supplier<String>() {
            @Override
            public String get() {
                return UUID.randomUUID().toString().replaceAll("-", "");
            }
        };
        log.info("学习使用Supplier lambda result:[{}]",supplier2.get());


    }


    /**
     * 学习使用consumer , 遍历输出学员的名称
     * <p>
     *     public void ifPresent(Consumer<? super T> consumer)
     * </p>
     */
    public static void testConsumer(){
        Result<List<String>> result = new Result<>();
        List<String> names = new ArrayList<>(10);
        names.add("a");names.add("b");names.add("c");names.add("d");names.add("e");
        Optional<List<String>> optional = Optional.of(names);
        // public void ifPresent(Consumer<? super T> consumer)
        optional.ifPresent(result::setData);
        log.debug("testConsumer result1:[{}]", JSONObject.toJSONString(result));


        // 方式1 使用lambda实现
        Stream<String> streamStr = Stream.of("a", "b", "c", "d", "e", "f", "g", "h");
        //lambda表达式返回的就是一个Consumer接口
        Consumer<String> consumer1 = (s) -> log.debug("testConsumer lambda name:[{}]",s);;
        streamStr.forEach(consumer1);
        Consumer consumer3 = System.out::println;
        Stream.of("a", "b", "c", "d", "e", "f", "g", "h").forEach(consumer3);

        Stream.of("a", "b", "c", "d", "e", "f", "g", "h").forEach(item ->{
            log.debug("testConsumer lambda2 name:[{}]",item);
        });




        // 方式2 使用普通 接口实现的方式
        Consumer<String> consumer2 = new Consumer<String>() {
            @Override
            public void accept(String s) {
                log.debug("testConsumer 接口实现的方式 name:[{}]",s);
            }
        };
        Stream.of("a", "b", "c", "d", "e", "f", "g", "h").forEach(consumer2);
        
    }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值