在Java8之前面对大型数据集合,Java 还欠缺高效的并行操作,为了编写这类处理批量数据的并行类库,同时也是为了更好的支持函数式编程,在语言层面上修改了现有的 Java:增加 Lambda 表达式。
Lambda表达式能够简化原来冗杂的样板代码,如
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("button clicked");
}
});
//以上代码可以简化为如下代码
button.setOnClickListener(v -> System.out.println("button clicked"));
Lambda表达式有以下几种形式:
//1、无参形式
Runnable runnable = () -> System.out.println("无参数");
//2、一个参数形式
View.OnClickListener listener = v -> System.out.println("一个参数");
View.OnClickListener listener = v -> {
System.out.println("一个参数");
System.out.println("一个参数");//多个语句可以使用代码块
};
//3、两个参数或多个形式
BinaryOperator add = (x, y) -> x + y;
BinaryOperator add = (Long x, Long y) -> x + y;//也可以显式的指定类型
有一点值得注意,Lambda表达式赋值的变量如上面的add
表示的不是x + y
的结果,而是x + y
本身这个表达式。
Lambda 表达式的类型:函数接口(Function Interface)。函数接口就是只有一个抽象方法的接口(由@FunctionalInterface
注解标识)!
图中绿色表示主要引入的新接口,其他接口基本上都是为了支持基本类型而添加的接口。
与面向对象主要抽象数据不同,函数式编程主要是为了抽象行为。函数式编程的核心是:在思考问题时,使用不可变值和函数,函数对一个值进行处理,映射成另一个值!
JAVA 8提供了java.util.function包用于支持函数式编程,Function Interface主要分为以下四大类:Function、Predicate、Supplier、Consumer
一、功能性接口:Function
/**
* Represents a function that accepts one argument and produces a result.
* 功能性接口的接口定义为R apply(T t),它接收一个功能参数t,并返回一个功能结果R
* @since 1.8
*/
@FunctionalInterface
public interface Function {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
...
}
二、断言性接口:Predicate
/**
* Represents a predicate (boolean-valued function) of one argument.
*
* @since 1.8
*/
@FunctionalInterface
public interface Predicate {
/**
* Evaluates this predicate on the given argument.
* 断言接口主要应用于判断场景,其抽象接口为boolean test(T t) 类似返回值为Boolean的功能性接口
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
...
}
三、供给性接口:Supplier
/**
* Represents a supplier of results.
* 供应接口的定义为T get(),不接收任何参数,有返回值
* There is no requirement that a new or distinct result be returned each
* time the supplier is invoked.
* 不要求每次调用供应接口都必须返回一个新的或者特别的结果
* @param the type of results supplied by this supplier
*
* @since 1.8
*/
@FunctionalInterface
public interface Supplier {
/**
* Gets a result.
* @return a result
*/
T get();
}
四、消费性接口:Consumer
/**
* Represents an operation that accepts a single input argument and returns no
* result. Unlike most other functional interfaces, {@code Consumer} is expected
* to operate via side-effects.
* 消费性接口的定义为void accept(T t),接收一个参数t,没有返回值。
* 和大多功能性接口不同,Consumer接口期望执行带有副作用的操作
*(意思是操作可能会更改输入参数的内部状态)
* @param the type of the input to the operation
*
* @since 1.8
*/
@FunctionalInterface
public interface Consumer {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
...
}
示例
public class FunctionClassify {
/**
* 功能性接口:Function
* 功能性接口的接口定义为R apply(T t),它接收一个功能参数t,并返回一个功能结果R
*/
private static void test1() {
Function function = (String str) -> str.length() > 3;
System.out.println("function--" + function.apply("java"));
Function function2 = a -> a + 10;
System.out.println("function--" + function2.apply(3));
Function function3 = s -> s.length();
System.out.println("function--" + function3.apply("java"));
}
/**
* 断言性接口:Predicate
* 断言接口主要应用于判断场景,其抽象接口为boolean test(T t)
*/
private static void test2() {
Predicate predicate = str -> str.length() > 3;
System.out.println("predicate--" + predicate.test("java"));
Predicate predicate2 = a -> true;
System.out.println("predicate--" + predicate2.test(5));
Predicate predicate3 = s -> s.equalsIgnoreCase("Java");
System.out.println("predicate--" + predicate3.test("java"));
System.out.println("predicate--" + predicate3.test("javac"));
}
/**
* 供给性接口:Supplier
* 供应接口的定义为T get(),不接收任何参数,有返回值
*/
private static void test3() {
Supplier supplier = () -> "Java".toLowerCase();
System.out.println("supplier--" + supplier.get());
}
/**
* 消费性接口:Consumer
* 消费性接口的定义为void accept(T t),接收一个参数t,没有返回值。
*/
private static void test4() {
Consumer consumer = s -> {
System.out.println( "consumer--" + s.toUpperCase());
};
consumer.accept("Java");
}
public static void main(String[] args) {
test1();
test2();
test3();
test4();
}
}
//输出结果
function--true
function--13
function--4
predicate--true
predicate--true
predicate--true
predicate--false
supplier--java
consumer--JAVA
public class Test2 {
public static void main(String[] args) {
String msg = "Hello World";
CustomAction tCustomAction = System.out::println;
test(tCustomAction, msg);
}
static void test(CustomAction action, String str) {
/**
* 和前面几种内置函数接口一样,使用“函数式接口.方法”的形式实现某种行为
* @param action
* @param str
*/
action.execute(str);
}
}
@FunctionalInterface
interface CustomAction{
public void execute(T t);
}
Java函数式编程二