java8新特性系列之---函数式接口

一只会飞的鱼儿 1年前 ⋅ 1573 阅读
ad

一、函数式接口

函数式接口定义且只定义了一个抽象方法,函数式接口很有用,因为抽象方法的签名可以描述Lambda表达式的签名。

函数式接口示例

  • Predicate

      接口定义了一个 test 抽象方法,接收一个泛型T,并返回一个布尔型。 

// lambda 表达式 filter 过滤器的操作就是通过 Predicate 函数式接口实现的
list.stream().filter(f -> "value".equal(f.value) )
  • Consumer

      接口定义了一个 accept 抽象方法,接收泛型T对象,没有返回, ,例如   

pulic static void main(String[] args) {
        // 案例 1, 对入参进行消费,没有返回值
	Consumer<Integer> consumer = x -> {
		int a = x + 2;
		System.out.println(a);// 12
		System.out.println(a + "_");// 12_
	};
	consumer.accept(10);

        // 案例2,
	List<String> list = new ArrayList<>();
	list.forEach(item -> {
		System.out.println(item);
	});
}

 

  • Function 

      接口定义了一个 apply 方法,它接受一个泛型 T 对象返回一个 泛型 R对象。

     Function 方法还有很多类型

Function<T,R> 接收一个参数并返回结果的函数
BiFunction<T,U,R> 接受两个参数并返回结果的函数
DoubleFunction 接收一个double类型的参数并返回结果的函数
DoubleToIntFunction 接收一个double类型的参数并返回int结果的函数
DoubleToLongFunction 接收一个double类型的参数并返回long结果的函数
IntFunction 接收一个int类型的参数并返回结果的函数
IntToDoubleFunction 接收一个int类型的参数并返回double结果的函数
IntToLongFunction 接收一个int类型的参数并返回long结果的函数
LongFunction 接收一个long类型的参数并返回结果的函数
LongToDoubleFunction 接收一个long类型的参数并返回double结果的函数
LongToIntFunction 接收一个long类型的参数并返回int结果的函数
ToDoubleBiFunction<T,U> 接收两个参数并返回double结果的函数
ToDoubleFunction 接收一个参数并返回double结果的函数
ToIntBiFunction<T,U> 接收两个参数并返回int结果的函数
ToIntFunction 接收一个参数并返回int结果的函数
ToLongBiFunction<T,U> 接收两个参数并返回long结果的函数
ToLongFunction 接收一个参数并返回long结果的函数

 

public class Transaction {
	/**
	 * 年
	 */
	private final int year;

        public int getYear() {
		return year;
	}
}

public static void main(String[] args) {
        // 在此案例中map 接口接收了一个 Transaction 类, 返回了 int 类的 year。
        List<String> cities = transactions.stream()
		.map(transaction -> transaction.getYear())
		.distinct()
		.collect(toList());
}

 

如何自定义函数式接口?

函数式接口定义且只定义了一个抽象方法。并在接口上使用函数式接口注解  @FunctionalInterface,此注解作用:主要用于校验此函数式接口是否合法(校验此函数式接口类中是否只有一个抽象方法)。

// 案例一 :无参函数式接口
/**
 * 自定义函数式接口
 * 有且只有一个抽象方法
 *
 * 执行任务
 */
@FunctionalInterface
public interface JobFunction {
	abstract void execute();

	// 静态方法
	static void test1() {
		System.out.println("1");
	}

	// 默认方法
	default void test2() {
		System.out.println("2");
	}

	// 所有的类都继承于 Object 的方法 equals
	public boolean equals(Object var1);
}    

public static void main(String[] args) {

	// 第一种写法
	JobFunction jobFunction = new JobFunction() {
		@Override
		public void execute() {
			System.out.println("testFunction1");
		}
	};

	// 第二种写法
	JobFunction jobFunction2 = () -> System.out.println("testFunction2");

	jobFunction.execute();
	jobFunction2.execute();
}	    


// 案例二 :指定类型函数式接口
@FunctionalInterface
public interface TestFunctionInterfaceSpecType {
	String test(Integer t1, Integer t2);
}

public static void main(String[] args) {

	// 案例二:指定参数函数式接口
	TestFunctionInterfaceSpecType testFunctionInterface2 = new TestFunctionInterfaceSpecType() {
		@Override
		public String test(Integer t1, Integer t2) {
			return "第一个参数为:" + t1 + "  第二个参数为:" + t2;
		}
	};
	System.out.println(
		testFunctionInterface2.test(1024, 1024*4 )
	);

}


// 案例三 :泛型函数式接口
@FunctionalInterface
public interface TestFunctionInterface<R, T>{
	R operator(T t1, T t2);
}


public class FunctionTest {

	public static void main(String[] args) {
		// 第一种写法
		TestFunctionInterface<String,Integer> testFunctionInterface = new TestFunctionInterface<String,Integer>(){
			@Override
			public String operator(Integer t1, Integer t2) {
				return t1.toString() + "、"+t2.toString();
			}
		};

		System.out.println(
				testFunctionInterface.operator(111,2222)
		);
		
		// 第二种写法,将函数式接口封装在方法中进行调用
		System.out.println(
				operator(1,2,(Integer a, Integer b) -> { return a+b;})
		);
	}

        // 函数式接口封装入方法中进行调用
	public static Integer operator(Integer a, Integer b, TestFunctionInterface<Integer, Integer> of) {
		return of.operator(a, b);
	}
}

 

总结:

函数式接口的使用技巧,

  • 明确函数式接口的 函数描述符(也就是函数式接口的入参,及出参)
  • 确定函数式接口使用范围,例如 Function 接口可是使用在类型转换(入参是一个类,出参是一个类), Predicate 接口可以使用在判定(因为入参是一个类,出参是boolean)
  • 自定义函数式接口,记得要符合规范(有且只有一个抽象方法)

关于Webfunny

Webfunny专注于前端监控系统,前端埋点系统的研发。 致力于帮助开发者快速定位问题,帮助企业用数据驱动业务,实现业务数据的快速增长。支持H5/Web/PC前端、微信小程序、支付宝小程序、UniApp和Taro等跨平台框架。实时监控前端网页、前端数据分析、错误统计分析监控和BUG预警,第一时间报警,快速修复BUG!支持私有化部署,Docker容器化部署,可支持千万级PV的日活量!

  点赞 0   收藏 0
  • 一只会飞的鱼儿
    共发布53篇文章 获得8个收藏
全部评论: 0