您的位置:首页 > 编程语言 > Java开发

java8函数式接口——Precidate、Consumer、Function、Supplier

2018-01-05 16:42 429 查看
本文主要介绍java8的提供的几种函数式接口的使用

Precidate

先看下他的源码

@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);

default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}

default Predicate<T> negate() {
return (t) -> !test(t);
}

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);
}
}


可以看到Predicate中有5个方法,现在咱们来写5个demo看看每个方法的用法

1. test(T t)

public class PredicateTest {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "bb", "ccc", "dddd", "eeeee", "ffffff");

//        List<String> filter = filter(list, (String s) -> s.length() > 2);
List<String> filter1 = filter(list, (s) -> s.length() > 2);
for (String s : filter1) {
System.out.println(s);
}

System.out.println("-----------------");
List<String> filter2 = filter(list, (s) -> s.equals("ccc"));
for (String s : filter2) {
System.out.println(s);
}
}

public static List<String> filter(List<String> list,Predicate<String> p){
List<String> result = new ArrayList<>();
for (String s : list) {
if(p.test(s)){
result.add(s);
}
}
return result;
}
}


test()方法接收一个参数,返回boolean值,我这里传入lambda表达式,使用lambda可以更灵活的完成一些功能

关于lambda表达式的使用请查看我的另外一篇博客:http://blog.csdn.net/KevinDai007/article/details/79299632

2. and(Predicate<? super T> other)

public class PredicateTest02 {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "bb", "ccc", "dddd", "eeeee", "ffffff");

Predicate<String> p1 = (s) -> s.length() > 2;
Predicate<String> p2 = (s) -> s.equals("dddd");

Predicate<String> and = p1.and(p2);
List<String> filter = filter(list, and);
for (String s : filter) {
System.out.println(s);
}
}

public static List<String> filter(List<String> list,Predicate<String> p){
List<String> result = new ArrayList<>();
for (String s : list) {
if(p.test(s)){
result.add(s);
}
}
return result;
}
}


and()方法接收Predicate类型且返回Predicate类型,可以进行链式判断,类似&&

3. and(Predicate<? super T> other)

public class PredicateTest03 {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "bb", "ccc", "dddd", "eeeee", "ffffff");

Predicate<String> p1 = (s) -> s.length() > 2;
Predicate<String> p2 = (s) -> s.equals("a");

Predicate<String> or = p1.or(p2);
List<String> filter = filter(list, or);
for (String s : filter) {
System.out.println(s);
}
}

public static List<String> filter(List<String> list,Predicate<String> p){
List<String> result = new ArrayList<>();
for (String s : list) {
if(p.test(s)){
result.add(s);
}
}
return result;
}
}


or()方法接收Predicate类型且返回Predicate类型,可以进行链式判断,类似||

4. Predicate negate()

public class PredicateTest04 {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "bb", "ccc", "dddd", "eeeee", "ffffff");

Predicate<String> p1 = (s) -> s.length() > 2;
Predicate<String> negate = p1.negate();
List<String> filter = filter(list, negate);
for (String s : filter) {
System.out.println(s);
}
}

public static List<String> filter(List<String> list,Predicate<String> p){
List<String> result = new ArrayList<>();
for (String s : list) {
if(p.test(s)){
result.add(s);
}
}
return result;
}
}


negate()方法就是将test()方法的值取非

5. static Predicate isEqual(Object targetRef)

public class PredicateTest04 {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "bb", "ccc", "dddd", "eeeee", "ffffff");

Predicate<String> p1 = (s) -> s.length() > 2;
Predicate<String> negate = p1.negate();
List<String> filter = filter(list, negate);
for (String s : filter) {
System.out.println(s);
}
}

public static List<String> filter(List<String> list,Predicate<String> p){
List<String> result = new ArrayList<>();
for (String s : list) {
if(p.test(s)){
result.add(s);
}
}
return result;
}
}


isEqual()方法接收一个object返回一个Predicate,用于查找与传入的对象相同的对象;如果传入的是null,则查找null

以上四种方法可灵活组合使用

从这些方法可以看出,Predicate接口主要作用是判断,例如在filter的方法中,Predicate通过接收判断的表达式或者方法,来判断对元素的操作.

Consumer

先看下他的源码

@FunctionalInterface
public interface Consumer<T> {

void accept(T t);

default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}


1. void accept(T t)

public class ConsumerTest01 {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "bb", "ccc", "dddd", "eeeee", "ffffff");

Consumer<String> print = (s) -> System.out.println(s);
Consumer<String> printLength = (s) -> System.out.println(s.length());

filter(list,print);
filter(list,printLength);

}

public static void filter(List<String> list,Consumer<String> consumer){
for (String s : list) {
consumer.accept(s);
}
}
}


accept()方法接收一个Object但没有返回值

2. default Consumer andThen(Consumer<? super T> after)

public class ConsumerTest02 {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "bb", "ccc", "dddd", "eeeee", "ffffff");

Consumer<String> print = (s) -> System.out.println(s);
Consumer<String> printLength = (s) -> System.out.println(s.length());

filter(list,print.andThen(printLength));

}

public static void filter(List<String> list,Consumer<String> consumer){
for (String s : list) {
consumer.accept(s);
}
}
}


andThen()方法接收Consumer且返回Consumer,可进行链式操作,与Precidate中and()方法十分类似

由上面两个方法可以看到Consumer是要对某元素进行操作的函数接口

Function

先看看它的源码

@FunctionalInterface
public interface Function<T, R> {

R apply(T t);

default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}

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;
}
}


直接看demo

1. R apply(T t)

public class FunctionTest01 {

public static void main(String[] args) {
List<String> list = Arrays.asList("1", "22", "333", "4444", "55555", "666666");

Function<String,Integer> valueOf = (s) -> Integer.valueOf(s);
Function<String,Integer> length = (s) -> s.length();

List<Integer> filter = filter(list, valueOf);
for (Integer integer : filter) {
System.out.println(integer);
}

System.out.println("-----------");

List<Integer> filter1 = filter(list, length);
for (Integer integer : filter1) {
System.out.println(integer);
}
}

public static List<Integer> filter(List<String> list,Function<String,Integer> consumer){
List<Integer> result = new ArrayList<>();
for (String s : list) {
result.add(consumer.apply(s));
}

return result;
}
}


Function <T,R>类有两个泛型参数,T代表入参类型,R代表返回类型

2. default <V> Function<V, R> compose(Function<? super V, ? extends T> before)

public class FunctionTest02 {
public static void main(String[] args) {
List<String> list = Arrays.asList("1", "22", "333", "4444", "55555", "666666");

Function<String,String> valueOf = (s) -> s + "aaa";
Function<String,String> length = (s) -> s += s;

List<String> filter = filter(list, valueOf.compose(length));
for (String integer : filter) {
System.out.println(integer);
}
}

public static List<String> filter(List<String> list,Function<String,String> consumer){
List<String> result = new ArrayList<>();
for (String s : list) {
result.add(consumer.apply(s));
}

return result;
}
}


compose()方法接收Function且返回Function,用于合并两个操作,且先执行参数中函数再执行调用的函数.用数学的方式可表示为valueOf(length(x))

3. default <V> Function<T, V> andThen(Function<? super R, ? extends V> after)

public class FunctionTest03 {
public static void main(String[] args) {
List<String> list = Arrays.asList("1", "22", "333", "4444", "55555", "666666");

Function<String,String> valueOf = (s) -> s + "aaa";
Function<String,String> length = (s) -> s += s;

List<String> filter = filter(list, valueOf.andThen(length));
for (String integer : filter) {
System.out.println(integer);
}
}

public static List<String> filter(List<String> list,Function<String,String> consumer){
List<String> result = new ArrayList<>();
for (String s : list) {
result.add(consumer.apply(s));
}

return result;
}
}


andThen()方法也是接收一个Function且返回Function,用于合并两个操作,但与compose不同的是,andThen()方法先执行调用的函数,再执行参数中的函数.用数学的方式可表示为length(valueOf(x))

4. static <T> Function<T, T> identity()

public class FunctionTest04 {
public static void main(String[] args) {
List<String> list = Arrays.asList("1", "22", "333", "4444", "55555", "666666");

Function<String, String> identity = Function.identity();
List<String> filter1 = filter(list, identity);
for (String integer : filter1) {
System.out.println(integer);
}
}

public static List<String> filter(List<String> list,Function<String,String> consumer){
List<String> result = new ArrayList<>();
for (String s : list) {
result.add(consumer.apply(s));
}
return result;
}
}


identity()方法简单的返回入参

由上面几个方法可以看出,Function可以理解为映射(或者说可以用来做映射),即将T映射为R

Supplier

先来看看它的源码

@FunctionalInterface
public interface Supplier<T> {
T get();
}


1. T get()

public class Supplier01 {
public static void main(String[] args) {
Supplier<String> supplier1 = () -> "test01";
Supplier<String> supplier2 = () -> "test02";

String s1 = filter(supplier1);
System.out.println(s1);

System.out.println("-------------");

String s2 = filter(supplier2);
System.out.println(s2);
}

public static String filter(Supplier<String> supplier){
return supplier.get();
}
}


get()方法没有入参,有返回值,可理解为产生一个对象.与其操作相似度的有Callable的call()方法

至此java8中几个常用的函数式接口的用法已全部了解完了,相信大家也看到了使用函数式接口的灵活性,以后在实际项目中多多使用吧

markdown语法不一致真的好烦,排版都调了半天
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: