java 8 函数式接口笔记(Predicate,Function,Comparator)

1.Predicate<T> 函数

官方注释: 表示一个参数的谓词(布尔值函数)。

 个人理解这个函数就是和断言差不多,核心是test()方法,返回一个Boolean类型的值,用来判断。一般配合stream的filter使用。

boolean test(T t);

1.一个简单的例子:

新建一个Predicate,并实现test方法,判断 t 是否大于3.

        // lambda
        Predicate<Integer> predicate = t -> t > 3;
        // 正常实现
        Predicate<Integer> predicate = new Predicate<Integer>() {
            @Override
            public boolean test(Integer t) {

                return t > 3;
            }
        };

2.配置stream的filter使用:

  @Test
    public void test() {
        // lambda
        Predicate<Integer> predicate = t -> t > 3;
        // 正常实现
        Predicate<Integer> predicate1 = new Predicate<Integer>() {
            @Override
            public boolean test(Integer t) {

                return t > 3;
            }
        };

        List<Integer> collect = CollUtil.newArrayList(11, 22, 3).stream().filter(predicate).collect(Collectors.toList());

        System.out.println(collect);
    }

结果:[11, 22];过滤掉了小于等于3的值。

执行的时候filter会执行predicate的test方法,然后过滤掉返回结果为false的数值。

3.and ()方法,逻辑与操作

  @Test
    public void test() {
        // lambda
        Predicate<Integer> predicate = t -> t > 3;

        Predicate<Integer> predicate1 = t -> t < 20;

        List<Integer> collect = CollUtil.newArrayList(11, 22, 3).stream().filter(predicate.and(predicate1)).collect(Collectors.toList());

        System.out.println(collect);
    }

例子的结果显而易见,大于3小于20的结果为【11】。

4.or()方法,逻辑或操作,用法和and相同

5.negate()方法,取非操作。

 @Test
    public void test() {
        // lambda
        Predicate<Integer> predicate = t -> t > 3;

        Predicate<Integer> predicate1 = t -> t < 20;

        System.out.println(predicate.and(predicate1).test(6)); // true
        System.out.println(predicate.or(predicate1).test(30));// true
        System.out.println(predicate.negate().test(1));// true

    }

6.isEqual()方法,调用的object的equals方法,会先判断object是否为null,不需要自己判断了,避免NPE。

方法定义:

 static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

例子:

  @Test
    public void test() {

        String strNull = null;
        String str = "str";
        System.out.println(Predicate.isEqual(null).test(str));
        System.out.println("~~~   ~~~   ~~~   ~~~");
        System.out.println(Predicate.isEqual(str).test("str"));
        System.out.println("~~~   ~~~   ~~~   ~~~");
        System.out.println(Predicate.isEqual(str).test("111"));
        System.out.println("~~~   ~~~   ~~~   ~~~");
    }

结果:

false
~~~   ~~~   ~~~   ~~~
true
~~~   ~~~   ~~~   ~~~
false
~~~   ~~~   ~~~   ~~~

2.Function<T,R> 函数

个人理解这是个映射处理的函数,里面的核心方法apply();

R apply(T t);

接受一个T类型处理成返回值R类型;里面的操作可以是任意的;

1.简单例子:

要实现apply方法。

    @Test
    public void test() {
        // lambada
        Function<Integer, String> function = integer -> integer + "";
        // 普通方式
        Function<Integer, String> function1 = new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) {
                return integer + "";
            }
        };
    }

结合stream使用:我们在数字后面 加上了str,现在用map()方法执行一遍:

  @Test
    public void test() {
        // lambada
        Function<Integer, String> function = integer -> integer + "str";

        List<String> collect1 = CollUtil.newArrayList(11, 22, 3).stream().map(function).collect(Collectors.toList());

        System.out.println(collect1);
    }

结果:[11str, 22str, 3str] 

集合里面的数字后面都加上了str的后缀。map()方法会执行function的apply方法,获取返回结果。前面说的映射处理也是和这里有些关系的。

2.compose()和andThen()方法

 @Test
    public void test() {
        // (integer*10)+str+andThen
        Function<Integer, String> function = integer -> integer + "str";
        function = function.andThen(s -> s + "andThen");
        function = function.compose(integer -> integer * 10);
        
        System.out.println(function.apply(8));
        
        // (x+20)*10 + 10
        Function<Integer, Integer> function1 = (x -> x * 10);
        function1 = function1.compose(x -> x + 20);
        function1 = function1.andThen(x -> x + 10);
        
        System.out.println(function1.apply(8));
    }

结果:80strandThen
          290

显而易见,compose是对R apply(T)的调用之前的T类型入参做处理的,反之andThen对方法执行完毕 R 类型返回值进行2次处理。

3.identity()方法,返回入参本身,不做处理,源代码如下:

static <T> Function<T, T> identity() {
        return t -> t;
    }

3.Comparator<T> 函数

这个函数是个比较的,和比较器一样的功能,核心方法是compare(T o1, T o2);

简单例子:

  // lambda
        Comparator<Integer> comparator = (o1, o2) -> o1 - o2;
        // 普通实现
        Comparator<Integer> comparator1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        };
  

比较数字的大小升序排列 

 @Test
    public void test() {
        // lambda
        Comparator<Integer> comparator = (o1, o2) -> o1 - o2;

        ArrayList<Integer> list = CollUtil.newArrayList(11, 22, 3, 6);

        list.sort(comparator);
        System.out.println(list);
    }

结果:[3, 6, 11, 22]

2.reversed()方法,逆转排序,还是比较常用的

  @Test
    public void test() {
        // lambda
        Comparator<Integer> comparator = (o1, o2) -> o1 - o2;

        ArrayList<Integer> list = CollUtil.newArrayList(11, 22, 3, 6);

        list.sort( comparator.reversed());
        System.out.println(list);
    }

结果:[22, 11, 6, 3]

我们的例子本来是升序,使用reversed方法逆转排序规则,就变成了降序排列;

3.thenComparing()方法

有时我们会遇到二次排序的需求,这是需要使用thenComparing()方法

简单例子:我们先根据姓名长度排序,再按照年龄大小排序;

构造一个用户类,有两个属性,姓名和年龄

@Data
@ToString
@AllArgsConstructor
public class User {
    private String name;
    private Integer age;
}

测试方法:

    @Test
    public void test() {
        // 姓名长度比较函数
        Comparator<User> comparatorName = (o1, o2) -> o1.getName().length() - o2.getName().length();
        // 年龄比较函数
        Comparator<User> comparatorAge = (o1, o2) -> o1.getAge() - o2.getAge();
        ArrayList<User> users = CollUtil.newArrayList(
                new User("zhangsan", 20),
                new User("lisi", 27),
                new User("wangwu", 21),
                new User("yuyu", 26));

        users.sort(comparatorName);
        System.out.println("按照姓名排序" + users);

        users.sort(comparatorName.thenComparing(comparatorAge));
        System.out.println("按照姓名排序然后按照年龄排序" + users);
    }

结果:

按照姓名排序[User(name=lisi, age=27), User(name=yuyu, age=26), User(name=wangwu, age=21), User(name=zhangsan, age=20)]
按照姓名排序然后按照年龄排序[User(name=yuyu, age=26), User(name=lisi, age=27), User(name=wangwu, age=21), User(name=zhangsan, age=20)]

上述代码可简化:

// 姓名长度比较函数
        Comparator<User> comparatorName = Comparator.comparingInt(o -> o.getName().length());
        // 年龄比较函数
        Comparator<User> comparatorAge = Comparator.comparingInt(User::getAge);

使用静态方法和function函数;

发布了47 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/oschina_40730821/article/details/99738206