如果需要使用Lambda接口,就必须要有一个函数式接口
函数式接口是有且仅有一个抽象方法的接口, 对应的注解是@FunctionalInterface
Java中内置的常见函数式接口如下:
1.Runnable/ Callable
/**
* The Runnable
interface should be implemented by any
* class whose instances are intended to be executed by a thread. The
* class must define a method of no arguments called run
.
*
* This interface is designed to provide a common protocol for objects that
* wish to execute code while they are active. For example,
* Runnable
is implemented by class Thread
.
* Being active simply means that a thread has been started and has not
* yet been stopped.
*
* In addition, Runnable
provides the means for a class to be
* active while not subclassing Thread
. A class that implements
* Runnable
can run without subclassing Thread
* by instantiating a Thread
instance and passing itself in
* as the target. In most cases, the Runnable
interface should
* be used if you are only planning to override the run()
* method and no other Thread
methods.
* This is important because classes should not be subclassed
* unless the programmer intends on modifying or enhancing the fundamental
* behavior of the class.
*
* @author Arthur van Hoff
* @see java.lang.Thread
* @see java.util.concurrent.Callable
* @since JDK1.0
*/
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface Runnable
is used
* to create a thread, starting the thread causes the object's
* run
method to be called in that separately executing
* thread.
*
* The general contract of the method run
is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
分别用匿名内部类和Lambda实现Runnable
public class RunnableLambda {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name);
}
}).start();
new Thread(()->{
String name = Thread.currentThread().getName();
System.out.println(name);
}).start();
}
}
Callable和Runnable类似
2.Supplier
特点:无方法参数, 返回值为定义的泛型
JDK中Supplier对应的定义:
package java.util.function;
/**
* Represents a supplier of results.
*
* There is no requirement that a new or distinct result be returned each
* time the supplier is invoked.
*
*
This is a functional interface
* whose functional method is {@link #get()}.
*
* @param the type of results supplied by this supplier
*
* @since 1.8
*/
@FunctionalInterface
public interface Supplier {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
Supplier的使用
public class SupplierLambda {
public static void main(String[] args) {
int[] arr = {2, 5, 8, 10, 500, 500, 50000};
int max = getMax(() -> {
int curMax = arr[0];
for(int i = 1; i < arr.length; i++) {
if(arr[i] > curMax) {
curMax = arr[i];
}
}
return curMax;
});
System.out.println(max);
}
public static int getMax(Supplier supplier) {
return supplier.get();
}
}
3.Consumer
特点:一个输入参数 无输出 可以对一个入参进行多次使用(使用andThen)
JDK中Consumer的定义
package java.util.function;
import java.util.Objects;
/**
* 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.
*
* This is a functional interface
* whose functional method is {@link #accept(Object)}.
*
* @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);
/**
* Returns a composed {@code Consumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @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 andThen(Consumer super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
Consumer的使用
import java.util.function.Consumer;
public class ConsumerLambda {
public static void main(String[] args) {
consumerString(s-> System.out.println(s.toUpperCase()),
s-> System.out.println(s.toLowerCase()));
}
static void consumerString(Consumer comsumer) {
comsumer.accept("Hello");
}
static void consumerString(Consumer firstConsumer, Consumer secondConsumer) {
firstConsumer.andThen(secondConsumer).accept("Hello");
}
}
4.Comparator
特点:两个参数(类型根据指定的泛型),返回值为int
JDK中关于Comparator的定义太长有500多行,我这里就不贴了,自己去看吧
使用如下:
import java.util.Arrays;
import java.util.Comparator;
public class ComparatorLambda {
public static void main(String[] args) {
String[] strs = {"delay","a", "ab", "abc", "bcd"};
Comparator comparator = new Comparator() {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
};
Arrays.sort(strs, comparator);
System.out.println(Arrays.toString(strs));
Arrays.sort(strs, (o1, o2)-> o2.length() - o1.length());
System.out.println(Arrays.toString(strs));
}
}
5.Predicate
特点:一个入参(类型由泛型指定),出参为boolean,内含条件判断方法,常用于判断
JDK中的定义如下:
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);
}
}
简单用法
import java.util.function.Predicate;
public class PredicateLambda {
public static void main(String[] args) {
andMethod(s->s.contains("W"),
s-> s.contains("H"));
orMethod(s->s.contains("W"),
s-> s.contains("H"));
negateMethod(s->s.length()>5);
}
static void andMethod(Predicate first, Predicate second) {
boolean isValid = first.and(second).test("helloWorld");
System.out.println("字符串符合要求吗:" + isValid);
}
static void orMethod(Predicate first, Predicate second) {
boolean isValid = first.or(second).test("helloWorld");
System.out.println("字符串符合要求吗:" + isValid);
}
static void negateMethod(Predicate predicate) {
boolean tooLong = predicate.negate().test("helloWorld");
System.out.println("字符串特别长吗:" + tooLong);
}
6.Function
特点:一个入参,有出参,入参和出参的类型都由泛型指定,可以多次处理(从第一个开始处理,然后把返回值作为第二个、第三个。。。的结果)
它的实例应该是具备某种功能的
简单使用如下:
import java.util.function.Function;
public class FunctionLambda {
public static void main(String[] args) {
method(str-> Integer.parseInt(str) + 10,
strInt -> strInt *= 10);
String str = "zhangsan,80";
int age = getAgeNum(str,
s->s.split(",")[1],
s->Integer.parseInt(s),
i-> i -= 10
);
System.out.println("zhangsan十年前的年龄是:" + age);
}
static void method(Function first, Function second) {
int num = first.andThen(second).apply("10");
System.out.println(num);
}
static int getAgeNum(String str, Function first,
Function second,
Function third) {
return first.andThen(second).andThen(third).apply(str);
}
}