软知识:
延迟方法:此方法会返回本接口类型,可以继续使用方法链调用(调用接口中的默认方法和抽象方法).通常函数式接口中的默认方法都是延迟方法;
终结方法:(抽象方法)此方法返回的类型不是本接口类型;所以就不能继续调用本接口中的抽象和默认方法;
接口:
java8之前;接口中只支持常量和抽象接口;
java8接口中引入了 默认方法(供子类重写,调用)和静态方法(接口直接调用);
java9接口中引入了 私有方法和静态私有方法;
函数式接口:
有且只有一个抽象方法;可以同时有默认方法,静态方法(JDK8新特性);
函数式接口,有且仅有一个抽象方法,Object的public方法除外。
注解标志: @FunctionalInterface;
1.生产者接口—-Supplier:
什么叫生产者接口?
英文释义—–>(n)供应商;供应者;
Supplier 没有默认方法和静态方法;
抽象方法:
T get();
测试:
@Test
public void testSupplier(){
Supplier<User> supplier = ()->new User();
//创建一个对象:
User user = supplier.get();
}
2.消费者接口—-Consumer(集合操作常用接口):
JDK8新特性:
接收一个输入参数并处理;不返回任何值;
抽象方法:
void accept(T t);
默认方法:
default Consumer<T> andThen(Consumer <? super T> after){
Objects.requireNonNull(after);
return (T t) - > {accept(t);after.accept(t)}
}
方法解释:
返回一个Consumer对象;
参数类型必须是当前对象的类型或者它的子类类型;
场景模拟:
xxxConsumer<T> A B;
A.andThen(B).accept(T);==A.accept(T);B.accept(T);
测试:
@Test
public void testConsumer{
String str = "helloworld";
Consumer<String> A = (str)->{str.sout}
A.accept(str);
Consumer<String> B = System.out::print;
A.andThen(B).accept(str);
}
3.Predicate接口(集合操作常用接口):
**抽象方法**:
boolean test(T t);
默认方法:
这三个方法都是返回一个测试对像;
当两个测试对象用下面的方法联合到一起调用的前提:
test()方法的参数相同!
//并且 and
Predicate<T> A,B; A.and(B).test(T);
default Predicate<T> and(Predicate <? super T>other){
Objects.requireNonNull(other);
return (t)->test(t)&&other.test(t);
}
//或者 or
Predicate<T> A ,B ; A.or(B).test(T);
default Predicate <T> or(Predicate<?super T> other){
Objects.requireNonNull(other);
return (t)->test(t)||other.test(t);
}
//取反
negate();//注意这个方法没有参数!
default Predicate<T> negate(){
return t->!test(t);
}
@Test
public void testPredicate(){
String[] strings = {"fsda","dsfa","ewr","ghfggf","iuiu"};
//数组对象得到stream;
//Stream stream = Stream.of(strings);
//Arrays.stream(strings);
//字符串测试对象A 返回长度大于3的字符串;
Predicate<String> A = str->str.length()>=3;
//字符串测试对象B 返回字符串中包含"a"的字符串;
Predicate<String> B = str->str.contains("a");
//输出字符串数组中长度大于3的字符串;
Arrays.stream(strings).filter(A::test).forEach(System.out::print);
//返回字符串中包含"i"的字符串或者长度大于3的字符串;
Arrays.stream(strings).filter(A.or(B)::test).forEach(System.out::print);
Arrays.stream(strings).filter(A.and(B)::test).forEach(System.out::println);
Arrays.stream(strings).filter(A.negate()::test).forEach(System.out::print);
Arrays.stream(strings).filter(A.or(B).negate()::test).forEach(System.out::print);
Arrays.stream(strings).filter(A.and(B).negate()::test).foreach(System.out::print);
}
4.Function接口:
自定义函数接口:
Function<T,R>
抽象方法:
R apply(T t);//方法实现了 传入一个 T 类型的数据返回一个 R 类型的数据;
默认方法:
default <V> Function<T,V> andThen(Function <? extends V> after){
Objects.requireNonNull;
return (T t)->after.apply(apply(t));
}
解释: 先执行第一个方法Function<T,V>返回一个 V 类型的数据 ,作为第二个方法的参数;
然后调用第二个方法Function<V,R>把V 作为参数传入第二个Function对象的apply方法中继续执行;
核心思想:第一个方法的返回值和第二个方法的参数的类型相同或者是其子类;
测试:
@Test
public void testFunction(){
Function<String,Integer> f1 = Integer::parseInt;
Function<Integer,Integer> f2 = n->n*10;
String str="12";
System.out.println(f1.apply(str)+1);
System.out.println(f1.andThen(f2).apply(str));
}