1. Lambda 的前世今生
在 Java 近年来的版本更新中,重大的版本更新莫过于 Java 5,在 Java 5 的更新中引入了“泛型”、“注解”、“枚举”和“自动拆装箱”等,本次在 Java 8 中引入 Lambda 的操作堪比 Java 5 的版本更新,Lambda 表达式用于替代函数式接口(比如 Runnbale),用于简化程序的复杂性。
同时在 Java 8 的版本中通过 Lambda 表达式增强集合的操作,引入了 ‘java.util.function’ 和 ‘java.util.stream’ 两个包,极大简化针对集合的操作。
在使用 Lambda 表达式的时候,个人认为会使程序可读性变差。
2. Lambda 表达式基本使用
2.1 基本语法
基本语法:
(parameters) -> expression
或
(parameters) ->{ statements; }
Lambda 表达式由参数、-> 和实现主体 三大部分组成。
2.2 常见格式
Lambda 表达式一些常见的格式:
// 1. 不需要参数,返回值为 2
() -> 2
// 2. 接收一个参数(数字类型),返回其3倍的值
x -> 3 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
针对具体的接口示例:
public class CreateSecretKey {
public static void main(String[] args) {
/**
* 无参数 lambda 表达式
*/
Runnable runnable = ()->{
System.out.println("No Parameters");
};
/**
* 一个参数的 lambda 表达式
*/
OneParameter oneParameter = x -> {
System.out.println("One Param:" + x);
};
/**
* 两个参数的 lambda 表达式
*/
TwoParameters twoParameters = (x, y) -> {
System.out.println("Two Param:" + x + ":" + y);
};
/**
* 字符串参数的 lambda 表达式
*/
StringParam strParam = str -> {
System.out.println("String Param:" + str.length());
};
}
}
interface OneParameter {
void oneParam(int one);
}
interface TwoParameters {
void twoParam(int one, int two);
}
interface StringParam {
void strParam(String str);
}
2.3 函数式接口
在 Java8 中引入了函数式接口的概念,函数式接口中只能定义一个抽象方法(除了隐含的Object对象的公共方法),这里不包含 default 和 static 修饰的方法。 因此最开始也就做SAM类型的接口(Single Abstract Method)。函数式接口通过注解 FunctionalInterface 进行标识。
比如在 JDK1.8 中的 Runnabhle 接口。
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
在 Java8 中引入了预置的四种函数接口:
- Function<T,R>:接受一个输入参数,返回一个结果
- Consumer:接受一个输入参数,无返回结果
- Predicate:接受一个输入参数,返回一个布尔类型结果
- Supplier:无参数,返回一个结果
1. Function<T,R> 接口
Function接口 接受一个输入参数T,返回一个结果R。
@FunctionalInterface
public interface Function<T, R> {
/**
* 给定一个值,返回处理结果
*/
R apply(T t);
/**
* 获取 function 接口 apply 方法,以 before 函数的 apply 方法结果作为参数
* @param before
* @return
*/
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
/**
* 返回一个 执行 after 函数对象 apply 方法的 函数对,after 函数参数是当前函数对象 apply 方法执行结果
* @param after
* @return
*/
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
示例:
定义一个 Function 对象。
Function<Integer, String> fun = new Function<Integer, String>() {
@Override
public String apply(Integer t) {
return "This is number:" + t;
}
};
Function 接口方法演示
public static void main(String[] args) {
Function<Integer, String> fun = new Function<Integer, String>() {
@Override
public String apply(Integer t) {
return "This is number:" + t;
}
};
Function<Integer, Integer> funCompose = new Function<Integer, Integer>() {
@Override
public Integer apply(Integer t) {
return t + 5;
}
};
Function<String, String> funAndThen = new Function<String, String>() {
@Override
public String apply(String t) {
return "The result:" + t;
}
};
String result = fun.apply(1);
System.out.println(result);
String compose = fun.compose(funCompose).apply(5);
System.out.println(compose);
String andThen = fun.andThen(funAndThen).apply(8);
System.out.println(andThen);
}
// 输出结果
This is number:1
This is number:10
The result:This is number:8
在上面的演示示例中,我们可以结合 lambda 表达式进行优化。
public static void main(String[] args) {
Function<Integer, String> fun = new Function<Integer, String>() {
@Override
public String apply(Integer t) {
return "This is number:" + t;
}
};
String compose = fun.compose((Integer x)->{
return x+5;
}).apply(5);
System.out.println(compose);
String andThen = fun.andThen((String apply)->{
return "The result:" + apply;
}).apply(8);
System.out.println(andThen);
}
// 输出结果
This is number:1
This is number:10
The result:This is number:8
2. Consumer 接口
代表了 接受一个输入参数并且无返回的操作。
@FunctionalInterface
public interface Consumer<T> {
/**
* 接收参数执行操作,无返回值
* @param t the input argument
*/
void accept(T t);
/**
* 限制性 accept 方法,再执行 after 的 accept 方法。
* @param after the operation to perform after this operation
* @return a composed {@code Consumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
示例:
public static void main(String[] args) {
Consumer<Integer> consumer = new Consumer<Integer>() {
@Override
public void accept(Integer t) {
System.out.println("This is accept number:" + t);
}
};
consumer.andThen((Integer x)->{
System.out.println("This is after accept number:" + x);
}).accept(5);;
}
// 执行结果
This is accept number:5
This is after accept number:5
3. Predicate 接口
输入一个参数,返回一个布尔类型结果。
@FunctionalInterface
public interface Predicate<T> {
// 执行判断 test 逻辑
boolean test(T t);
// 当前 Predicate 和 other 的运算结果进行 and 运算
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
// Preidcate 接口进行取反
default Predicate<T> negate() {
return (t) -> !test(t);
}
// 当前 Predicate 和 other 的运算结果进行 or 运算
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
// 判断 是否相等
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
示例:
public static void main(String[] args) {
Predicate<Integer> predicate = new Predicate<Integer>() {
@Override
public boolean test(Integer t) {
if (t > 5) {
return false;
} else {
return true;
}
}
};
System.out.println("test:" + predicate.test(5));//以 5 计算,返回 true
System.out.println("negate:" + predicate.negate().test(5)); //进行 test 的取反,为 false
System.out.println("isEqual:" + Predicate.isEqual(6).test(5));//判断是否相等,不相等,false
boolean and = predicate.and((Integer x)->{
if (x >10) {
return false;
} else {
return true;
}
}).test(6);
System.out.println("and:" + and);//and 运算,一真一假为false
boolean or = predicate.or(x ->{
if (x > 10 ) {
return false;
} else {
return true;
}
}).test(6);
System.out.println("or:" + or);//or 运算,一真一假为true
}
//结果
test:true
negate:false
isEqual:false
and:false
or:true
4. Supplier 接口
无参数返回一个结果。
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
示例:
public static void main(String[] args) {
Supplier<Integer> supplier = new Supplier<Integer>() {
@Override
public Integer get() {
return 5;
}
};
System.out.println(supplier.get());
}
//结果
5
下节中将介绍 Stream 的使用。