1.1、概述
函数式接口:有且仅有一个抽象方法的接口
1.2、函数式接口作为方法的参数
需求:如果方法的参数是一个函数式接口,我们可以使用Lambda表达式作为参数传递
start
package com.itheima01;
public class RunnableDemo {
public static void main(String[] args) {
// 使用匿名内部类的方法
startThread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程启动了");
}
});
startThread(()->{
// Thread.currentThread().getName()当前线程的名称
System.out.println(Thread.currentThread().getName()+"Lambda表达式启动了线程");
});
}
private static void startThread(Runnable r){
/* Thread t=new Thread();
t.start();*/
new Thread(r).start();
}
}
/*
函数式接口:标签 @FunctionalInterface
public interface Runnable {
*/
/*
* When an object implementing interface {@code Runnable} is used
* to create a thread, starting the thread causes the object's
* {@code run} method to be called in that separately executing
* thread.
* <p>
* The general contract of the method {@code run} is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*//*
public abstract void run();*/
1.3、函数式接口作为方法的返回值
需求:
package com.itheima02;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Objects;
public class ComparatorDemo {
public static void main(String[] args) {
//构造器使用场景
// 定义集合,存储字符串元素
ArrayList<String> array=new ArrayList<String>();
array.add("cccc");
array.add("aa");
array.add("b");
array.add("ddd");
System.out.println("排序前"+array);
Collections.sort(array);
System.out.println("用Collectios排序后"+array);
Collections.sort(array,Comparator());
System.out.println("用Comparator排序后"+array);
}
private static Comparator<String> Comparator(){
//匿名内部类的方式实现
/* Comparator<String> comp=new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.length()-s2.length();
}
};
return comp;*/
/*return new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.length()-s2.length();
}
};*/
/* return (String s1,String s2)->{
return s1.length()-s2.length();
};*/
return (s1,s2)->s1.length()-s2.length();
}
}
/*
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
default Comparator<T> thenComparing(Comparator<? super T> other) {
Objects.requireNonNull(other);
return (Comparator<T> & Serializable) (c1, c2) -> {
int res = compare(c1, c2);
return (res != 0) ? res : other.compare(c1, c2);
};
}
*/
1.5、Supplier接口
给定一个泛型用get()返回对应的类型
package com.itheima03;
import java.util.function.Supplier;
public class SupplierDemo {
public static void main(String[] args) {
String name=getString(()->{
return "林青霞";
});
System.out.println(name);
Integer age= getInteger(() -> 30);
System.out.println(age+1);
}
// 定义一个方法,返回一个字符串类型数据
private static String getString(Supplier<String> sup){
return sup.get();
}
// 定义一个方法,返回一个整数型数据
public static Integer getInteger(Supplier<Integer> sup){
return sup.get();
}
}
1.6、常用函数式接口Predicate
Predicate接口常用方法
package com.itheima06;
/*
Predicate<T>常用的的四个方法
boolean test(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
default Predicate<T>negate():返回一个逻辑的否定,对应逻辑非
default Predicate<T>and(Predicate other):返回一个组合判断,对应短路与
default Predicate<T>or(Predicate other):返回一个组合判断,对应短路或
Predicate<T>接口通常用于判断参数是否满足指定的条件
*/
import java.util.function.Predicate;
public class PredicateDemo {
public static void main(String[] args) {
// boolean test(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
boolean b1=checkString("hello",(String s)->s.length()>8);
System.out.println(b1);
// default Predicate<T>negate():返回一个逻辑的否定,对应逻辑非
}
private static boolean checkString(String s, Predicate<String> pre){
// return pre.test(s); //print:false
// return !pre.test(s);//等价于return pre.negate.test(s);
return pre.negate().test(s);
}
}
package com.itheima06;
import java.util.function.Predicate;
public class PreDicateDemo02 {
public static void main(String[] args) {
boolean b1=checkString("hello",s->s.length()>8,s->s.length()<15);
System.out.println(b1);
}
private static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2) {
/*boolean b1 = pre1.test(s);
boolean b2 = pre1.test(s);
boolean b = b1 && b2;
return b;*/
// return pre1.and(pre2).test(s);//false
return pre1.or(pre2).test(s);//true
}
}
package com.itheima06;
import java.util.ArrayList;
import java.util.function.Predicate;
public class PredicateTest {
public static void main(String[] args) {
// 定义strArrayList数组,存储需要筛选的元素
String []strArray={"林青霞,30","王祖贤,28","汤唯,24","叶倩文,31","周海媚,32"};
// 调用myFilter方法
ArrayList<String> resultArray=myFilter(strArray,s->s.split(",")[0].length()>2,
s->Integer.parseInt(s.split(",")[1])>28);
for (String ss:resultArray){
System.out.println(ss);
}
}
// 定义一个方法,传一个字符串集合,将集合姓名和年龄同时满足条件的元素添加到集合中
private static ArrayList<String> myFilter(String [] strArray, Predicate<String> pre1,Predicate<String> pre2){
// 定义一个ArrayList集合用来存储满足条件的元素
ArrayList<String> array=new ArrayList<String>();
// 将传入的集合进行遍历
for(String ss:strArray){
if (pre1.and(pre2).test(ss)){
array.add(ss);
}
}
return array;
}
}
1.8、Function接口
Function<T,R>常用的方法
R apply(T t):将此函数应用于给定的参数
default<V> Function andThen(Function after):返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果
Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现)然后返回一个新的值
练习
String s="王祖贤,20";
按照指定的要求进行操作
1、将字符串截取得到数组年龄部分
2、将上一步的年龄字符串转换为int类型的数据
3、将上一步的int数据加70,得到一个int结果,在控制台输出
package com.itheima07;
/*
String s="王祖贤,20";
按照指定的要求进行操作
1、将字符串截取得到数组年龄部分
2、将上一步的年龄字符串转换为int类型的数据
3、将上一步的int数据加80,得到一个int结果,在控制台输出
通过Function接口来实现数据拼接
*/
import java.util.function.Function;
public class FunctionTest {
public static void main(String[] args) {
String s="王祖贤,20";
// 第一个Function将字符串是中的年龄分割出来
convert(s,ss->ss.split(",")[1],
// 第二个Function分割出来的年龄字符串转换成int类型
// ss->Integer.parseInt(ss),
// 将字符串转换为int这一步可以用引用方法实现
Integer::parseInt,
// 第三个Function将int类型的数字+80
i->i+80);
}
// 定义一个方法
private static void convert(String s, Function<String,String> fun1,Function<String,Integer> fun2,Function<Integer,Integer> fun3){
Integer i = fun1.andThen(fun2).andThen(fun3).apply(s);
System.out.println(i);
}
}