Java函数式编程:一种令人懵逼的技术,但是真的很好用

需要注意,函数接口并不是只能有一个方法,可以是

多个默认实现了方法 + 1个未实现的非静态方法 的形式 ,如下:

@FunctionalInterface

interface Interface1{

// 1个未实现的非静态方法

int doubleNum(int i);

// 默认实现的方法

default int add(int x ,int y){

return x + y;

}

}

  1. 在 函数接口多重继承的时候,如果出现 同名的默认实现的方法,这个时候需要指定具体是哪个类的默认方法。

注意学习:接口的默认方法,如List

Java8 内置的函数接口

=============

java已经帮我们定义好了一些常用的函数接口,就不用我们自己去定义了,我们仅关注自己的实现逻辑即可;同时函数接口也支持链式编程

定义更少的接口,可以更加灵活的操作

那么常见内置的函数接口有哪些呢?

Java8之Predicate函数

=================

Predicate 一个函数式接口,属于java.util.function包,主要用来对输入的对象按照指定的条件进行过滤

大家不要对这种函数式接口抱有太大的畏惧心理,要我说,如果没有对应的场景,他就只是一堆代码而已,都是纸老虎!

Predicate就是一个接口,里面有且仅有一个抽象方法test方法:

boolean test(T t);

T是你传进去的参数,可以是任意类型,返回的是一个布尔值。意思就是:你给我一个值,我告诉你对不对?

这是一种操作,一种回调。它不是一种有方法体的函数,也就没有逻辑,逻辑是要你自己补充的。

我们先来一个简单的例子,有一个Person类,有name和sex字段,如果sex=男,我就输出“男孩”,简单吧!

class Person{

public Person(String name, String sex) {

this.name = name;

this.sex = sex;

}

String name;

String sex;

}

然后去判断是不是男的

Person jack = new Person(“jack”,“男”);

if(“男”.equals(jack.sex)){

System.out.println(jack.name + “是男的!”);

}

答案:jack是男的!

那么,我们如何用Predicate来实现这个场景呢?

public void test2(){

Person jack = new Person(“jack”,“男”);

/** 新建一个判断是否为Boy的匿名子类对象,别忘了全部加泛型否则会报错 * */

Predicate PredicateBody = new Predicate() {

@Override

public boolean test(Person o) {

return “男”.equals(o.sex);

}

};

if(PredicateBody.test(jack)){

System.out.println(jack.name + “是男的!”);

}

}

PredicateBody的生成方式可以换成Lamda,看起来更简洁一些。

IDEA还有贴心的提示,这也太牛了吧!

Predicate PredicateBody = o -> “男”.equals(o.sex);

什么,你还觉得不够爽?之前学了匿名子类对象的初始化,忍不住要试试?

行啊,试试就试试!


看代码:

if(new Predicate(){

@Override

public boolean test(Person person) {

return “男”.equals(person.sex);

}

}.test(jack)){

System.out.println(jack.name + “是男的!”);

}

如果这种Predicate对象其他方法也需要用怎么办?有一个技巧就是单独做一个方法,返回这种独有的Predicate对象。

/** 好耶!做成static任何地方想用就用啦! * */

public static Predicate PredicateBody (){

return new Predicate(){

@Override

public boolean test(Person person) {

return “男”.equals(person.sex);

}

};

}

然后是用的地方:

Person jack = new Person(“jack”,“男”);

if(PredicateBody().test(jack)){

System.out.println(jack.name + “是男的!”);

}

最后附上Predicate源码:

/*

  • Copyright © 2010, 2013, Oracle and/or its affiliates. All rights reserved.

  • ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.

*/

package java.util.function;

import java.util.Objects;

/**

  • Represents a predicate (boolean-valued function) of one argument.

  • This is a functional interface

  • whose functional method is {@link #test(Object)}.

  • @param the type of the input to the predicate

  • @since 1.8

*/

@FunctionalInterface

public interface Predicate {

/**

  • Evaluates this predicate on the given argument.

  • @param t the input argument

  • @return {@code true} if the input argument matches the predicate,

  • otherwise {@code false}

*/

boolean test(T t);

/**

  • Returns a composed predicate that represents a short-circuiting logical

  • AND of this predicate and another. When evaluating the composed

  • predicate, if this predicate is {@code false}, then the {@code other}

  • predicate is not evaluated.

  • Any exceptions thrown during evaluation of either predicate are relayed

  • to the caller; if evaluation of this predicate throws an exception, the

  • {@code other} predicate will not be evaluated.

  • @param other a predicate that will be logically-ANDed with this

  •          predicate
    
  • @return a composed predicate that represents the short-circuiting logical

  • AND of this predicate and the {@code other} predicate

  • @throws NullPointerException if other is null

*/

default Predicate and(Predicate<? super T> other) {

Objects.requireNonNull(other);

return (t) -> test(t) && other.test(t);

}

/**

  • Returns a predicate that represents the logical negation of this

  • predicate.

  • @return a predicate that represents the logical negation of this

  • predicate

*/

default Predicate negate() {

return (t) -> !test(t);

}

/**

  • Returns a composed predicate that represents a short-circuiting logical

  • OR of this predicate and another. When evaluating the composed

  • predicate, if this predicate is {@code true}, then the {@code other}

  • predicate is not evaluated.

  • Any exceptions thrown during evaluation of either predicate are relayed

  • to the caller; if evaluation of this predicate throws an exception, the

  • {@code other} predicate will not be evaluated.

  • @param other a predicate that will be logically-ORed with this

  •          predicate
    
  • @return a composed predicate that represents the short-circuiting logical

  • OR of this predicate and the {@code other} predicate

  • @throws NullPointerException if other is null

*/

default Predicate or(Predicate<? super T> other) {

Objects.requireNonNull(other);

return (t) -> test(t) || other.test(t);

}

/**

  • Returns a predicate that tests if two arguments are equal according

  • to {@link Objects#equals(Object, Object)}.

  • @param the type of arguments to the predicate

  • @param targetRef the object reference with which to compare for equality,

  •           which may be {@code null}
    
  • @return a predicate that tests if two arguments are equal according

  • to {@link Objects#equals(Object, Object)}

*/

static Predicate isEqual(Object targetRef) {

return (null == targetRef)

? Objects::isNull
object -> targetRef.equals(object);

}

}

Predicate自带的and方法怎么用?

=====================

看下源码:

default Predicate and(Predicate<? super T> other) {

Objects.requireNonNull(other);

return (t) -> test(t) && other.test(t);

}

意思就是加一个other的断言规则,返回的是自己(当前规则)和other规则判定的最终值(已经是一个布尔值了)之间的并集。

举个例子,一个person对象,我需要去判断他的name是否是jack,并且sex是否是男,代码如下。

Person jack = new Person(“jack”,“男”);

if(new Predicate(){

@Override

public boolean test(Person person) {

return “jack”.equals(person.name);

}

}.and(p -> “男”.equals(p.sex)).test(jack)){

System.out.println(jack.name + “是男的!”);

}else{

System.out.println(“判断出错!”);

}

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
、OPPO等大厂,18年进入阿里一直到现在。**

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-Pd1owyW5-1715724400898)]

[外链图片转存中…(img-fHCQtZLL-1715724400898)]

[外链图片转存中…(img-eTybNeHX-1715724400899)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值