如果需要使用Lambda接口,就必须要有一个函数式接口
函数式接口是有且仅有一个抽象方法的接口, 对应的注解是@FunctionalInterface
Java中内置的常见函数式接口如下:
1.Runnable/ Callable
/** * The <code>Runnable</code> 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 <code>run</code>. * <p> * This interface
is designed to provide a common protocol for objects that * wish to execute
code while they are active. For example, * <code>Runnable</code> is implemented
by class <code>Thread</code>. * Being active simply means that a thread has
been started and has not * yet been stopped. * <p> * In addition,
<code>Runnable</code> provides the means for a class to be * active while not
subclassing <code>Thread</code>. A class that implements *
<code>Runnable</code> can run without subclassing <code>Thread</code> * by
instantiating a <code>Thread</code> instance and passing itself in * as the
target. In most cases, the <code>Runnable</code> interface should * be used if
you are only planning to override the <code>run()</code> * method and no other
<code>Thread</code> 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 <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(); }
分别用匿名内部类和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. * *
<p>There is no requirement that a new or distinct result be returned each *
time the supplier is invoked. * * <p>This is a <a
href="package-summary.html">functional interface</a> * whose functional method
is {@link #get()}. * * @param <T> the type of results supplied by this supplier
* * @since 1.8 */ @FunctionalInterface public interface Supplier<T> { /** *
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<Integer> 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. * * <p>This is a <a href="package-summary.html">functional
interface</a> * whose functional method is {@link #accept(Object)}. * * @param
<T> the type of the input to the operation * * @since 1.8 */
@FunctionalInterface public interface Consumer<T> { /** * 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<T> 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<String> comsumer) {
comsumer.accept("Hello"); } static void consumerString(Consumer<String>
firstConsumer, Consumer<String> 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<String> comparator = new
Comparator<String>() { @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. * * <p>This is a <a
href="package-summary.html">functional interface</a> * whose functional method
is {@link #test(Object)}. * * @param <T> the type of the input to the predicate
* * @since 1.8 */ @FunctionalInterface public interface Predicate<T> { /** *
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. * * <p>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<T> 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<T> 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. * * <p>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<T> 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 <T> 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 <T>
Predicate<T> 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<String> first,
Predicate<String> second) { boolean isValid =
first.and(second).test("helloWorld"); System.out.println("字符串符合要求吗:" +
isValid); } static void orMethod(Predicate<String> first, Predicate<String>
second) { boolean isValid = first.or(second).test("helloWorld");
System.out.println("字符串符合要求吗:" + isValid); } static void
negateMethod(Predicate<String> 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<String, Integer> first, Function<Integer, Integer> second) {
int num = first.andThen(second).apply("10"); System.out.println(num); } static
int getAgeNum(String str, Function<String, String> first, Function<String,
Integer> second, Function<Integer, Integer> third) { return
first.andThen(second).andThen(third).apply(str); } }