1.函数式接口
举例复习接口的匿名实现
- 假设有接口 InterfaceA , 该接口中有抽象方法 T methodA(T t)
- 在一般情况下如果想要调用这个方法,需要创建一个类,这个类继承InterfaceA这个接口,并重写抽象方法,根据需求对方法进行具体的实现
- 假设现在有两个需求:
1) 现有List 集合,去除不包含’a’的数据并返回
2) 现有List 集合,去除不包含小于10的数据并返回
3) 在不使用接口匿名实现的情况下需要继承这个接口并重写两次抽象方法,进行具体实现,如果还需要去判断List,List ?
- 直接创建接口的对象,在大括号中重写抽象方法进行具体的实现
Runnable r1 = new Runnable(){
@Override
public void run(){
System.out.println("接口匿名实现类,重写抽象方法执行...");
}
};
r1.run();
函数式接口
- 什么是函数式接口: 只包含一个抽象方法的接口称为函数式接口,可以通过@FunctionalInterface 来检查创建的接口是否是函数式接口
- java8 在 java.util.function包下提供了预定义的函数式接口: 分为消费型, 供给型, 函数型, 断定型:
2. Lambda表达式
什么是Lambda:
- 可以理解为函数式接口的实例化,在通过Lambda不创建类的情况下匿名实现只有一个抽象方法的接口简化写法
- 示例:
Comparator<Integer> com1 = new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2){
return Integer.compare(01, 02);
}
};
int i1 = com1.compare(2,3);
System.out.println(i1);
Comparator<Integer> com2 = (o1, o2) -> Integer.compare(o1, o2);
int i2 = com2.compare(2,3);
System.out.println(i2);
Comparator<Integer> com3 = Integer :: compare;
int i3 = com3.compare(2,3);
System.out.println(i3);
Lambda的几种编写规则解释示例
@Test
public void test1(){
Runnable r1 = new Runnable(){
@Override
public void run(){
System.out.println("接口匿名实现类,重写抽象方法执行...");
}
};
r1.run();
Runnable r2 = () -> {
System.out.println("Lambda接口匿名实现类,重写抽象方法执行...");
};
Consumer<String> con = new Consumer<String>(){
@Override
public void accept(String s){
System.out.println(s);
}
};
Consumer<String> con2 =(String s) -> {
System.out.println(s);
};
Consumer<String> con3 = new Consumer<String>(){
@Override
public void accept(String s){
System.out.println(s);
}
};
Consumer<String> con4 = (s) -> {
System.out.println(s);
};
Consumer<String> con5 = s -> {
System.out.println(s);
};
Consumer<String> con6 = s -> System.out.println(s);
Comparator<Integer> com1 = new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2){
return Integer.compare(01, 02);
}
};
Comparator<Integer> com2 = (o1, o2) -> Integer.compare(o1, o2);
}
Lambda 的方法引用与构造器引用
方法引用的解释与编写:
- 当要传递给Lambda的方法体是一个已经实现的方法了,就可以使用方法引用,使用 " 类或对象 :: 属于该类或该对象的方法" 引用方法
- 方法引用的引用方式:
对象 :: 实例方法名 (该方法的形参列表与返回值类型必须与抽象方法保持一致)
类 :: 静态方法名 (该方法的形参列表与返回值类型必须与抽象方法保持一致)
类 :: 实例方法名 (特殊情况,类是方法体中用来调用另外一个实例方法的数据对象的类型)
方法引用示例:
public class ArrayTest {
@Test
public void testName2() {
ArrayTest objAt = new ArrayTest();
Consumer<String> con1 = strVal ->System.out.println("普通Lambda:"+strVal);
Consumer<String> con2 = objAt :: existMethod;
con2.accept("aaa");
Supplier<String> supplier1 = () -> ArrayTest.existMethodReturn();
Supplier<String> supplier2 = ArrayTest :: existMethodReturn;
String s = supplier2.get();
Comparator<Integer> com1 = (t1, t2) -> Integer.compare(t1, t2);
Comparator<Integer> com2 = Integer :: compare;
int i = com2.compare(2,3);
Comparator<String> com3 = (s1, s2) -> s1.compareTo(s2);
Comparator<String> com4 = String :: compareTo;
com4.compare("abc","abd");
BiPredicate<String, String> pre1 = (s1, s2) -> s1.equals(s2);
BiPredicate<String, String> pre2 = String :: equals;
Boolean b = pre2.test("aa","cc");
Function<ArrayTest, String> fun1 = arrayTest -> arrayTest.get();
Function<ArrayTest, String> fun2 = ArrayTest :: get;
fun2.apply(objAt);
}
public void existMethod(String str){
System.out.println("已经存在的方法:"+str);
}
public static String existMethodReturn(){
return "已存在静态方法返回参数";
}
public String get(){
return "已存在实例方法返回参数";
}
}
构造器引用示例
public class ArrayTest {
private String name;
private Integer age;
public ArrayTest(){
}
public ArrayTest(String name){
this.name = name;
}
public ArrayTest(String name, Integer age){
this.name = name;
this.age = age;
}
@Test
public void test4(){
Supplier<ArrayTest> supplier1 = () -> new ArrayTest();
Supplier<ArrayTest> supplier2 = ArrayTest :: new;
ArrayTest sArrayTest = supplier2.get();
Function<String, ArrayTest> fun1 = str -> new ArrayTest("小明");
Function<String, ArrayTest> fun2 = ArrayTest :: new;
ArrayTest fArrayTest = fun2.apply("小黑");
BiFunction<String, Integer, ArrayTest> bif1 = (name, age) -> new ArrayTest("小红", 13);
BiFunction<String, Integer, ArrayTest> bif2 = ArrayTest :: new;
ArrayTest bArrayTest = bif2.apply("小蓝", 15);
Function<Integer, String[]> funA1 = length -> new String[length];
Function<Integer, String[]> funA2 = String[] :: new;
String[] strArr = funA2.apply(10);
System.out.println(strArr.toString());
}
}
Lambda 使用示例
public class ArrayTest {
@Test
public void test1() {
this.testConsumer("aaa", new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("接口匿名实现消费输出:" + s);
}
});
this.testConsumer("bbb", stringVal -> System.out.println("Lambde消费输出:" + stringVal));
List<String> strList = new ArrayList<>();
strList.add("ccc");
strList.add("cac");
strList.add("bb");
strList.add("aaa");
List<String> returnList1 = this.filterString(strList, new Predicate<String>() {
@Override
public boolean test(String s) {
return s.contains("a");
}
});
List<String> returnlist2 = this.filterString(strList, strVal -> strVal.contains("c"));
Supplier<String> supplier2 = ArrayTest::existMethodReturn;
String s = supplier2.get();
Function<Double, Long> fun1 = d -> Math.round(d);
Function<Double, Long> fun2 = Math::round;
fun2.apply(2.5);
}
public void testConsumer(String val1, Consumer<String> con) {
con.accept(val1);
}
public List<String> filterString(List<String> strList, Predicate<String> pre) {
List<String> newList = new ArrayList<>();
for (String s : strList) {
if (pre.test(s)) {
newList.add(s);
}
}
return newList;
}
public static String existMethodReturn() {
return "已存在静态方法返回参数";
}
}