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函数;