函数式接口
(一)函数式接口概述
(二)函数式接口作为方法的参数
测试类:
public class RunnableDemo {
public static void main(String[] args) {
//匿名内部类
startThread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "启动了");
}
});
//Lambda表达式
startThread(() -> System.out.println(Thread.currentThread().getName() + "启动了"));
}
private static void startThread(Runnable r) {
new Thread(r).start();
}
}
(三)函数式接口作为方法的返回值
代码演示:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class ComparatorDemo {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<>();
array.add("aaabbb");
array.add("sdas");
array.add("sda");
System.out.println("排序前:" + array);//排序前:[aaabbb, sdas, sda]
Collections.sort(array, getComparator());
System.out.println("排序后:" + array);//排序后:[sda, sdas, aaabbb]
}
private static Comparator<String> getComparator() {
//匿名内部类实现
// Comparator<String> c = new Comparator<String>() {
// @Override
// public int compare(String s1, String s2) {
// return s1.length() - s2.length();
// }
// };
// return c;
//匿名内部类简写
// return new Comparator<String>() {
// @Override
// public int compare(String s1, String s2) {
// return s1.length() - s2.length();
// }
// };
//Lambda表达式
// return (String s1,String s2) -> {
// return s1.length() - s2.length();
// };
//Lambda表达式简写
return (s1, s2) -> s1.length() - s2.length();
}
}
(四)常用的函数式接口
Java8在java.util.function包下预定义了大量的函数式接口供我们使用
我们重点来学习下面的4个接口
- Supplier接口
- Consumer接口
- Predicate接口
- Function接口
1.Supplier接口
代码演示:
import java.util.function.Supplier;
public class SupplierDEmo {
public static void main(String[] args) {
// String s = getString(new Supplier<String>() {
// @Override
// public String get() {
// return "小明";
// }
// });
String s = getString(() -> "小明");
System.out.println(s);//小明
Integer i = getInteger(() -> 10);
System.out.println(i);//10
}
private static Integer getInteger(Supplier<Integer> sup){
return sup.get();
}
private static String getString(Supplier<String> sup) {
return sup.get();
}
}
2.Supplier接口练习(获取最大值)
代码演示:
import java.util.function.Supplier;
public class SupplierTest {
public static void main(String[] args) {
int[] arr = {19, 50, 28, 37, 46};
int maxValue = getMax(() -> {
int max = 0;
for (int i = 0; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
return max;
});
System.out.println(maxValue);
}
private static int getMax(Supplier<Integer> sup) {
return sup.get();
}
}
3.Consumer接口
代码演示:
import java.util.function.Consumer;
public class ConsumerDemo {
public static void main(String[] args) {
//匿名内部类
operatorString("小明", new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
//Lambda表达式
operatorString("小明", s -> System.out.println(s));
//方法引用
operatorString("小明", System.out::println);
operatorString("小明", s -> System.out.println(new StringBuilder(s).reverse().toString()));
operatorString("王老五", s -> System.out.println(s), s -> System.out.println(new StringBuilder(s).reverse().toString()));
}
private static void operatorString(String name, Consumer<String> con) {
con.accept(name);
}
//对同一个字符串数据用不同的方式消费两次
private static void operatorString(String name, Consumer<String> con1, Consumer<String> con2) {
con1.andThen(con2).accept(name);
}
}
4.Consumer接口练习(按要求打印信息)
代码演示:
import java.util.function.Consumer;
public class ConsumerTest {
public static void main(String[] args) {
String[] strArray = {"王老五,20", "张三,30", "李四,22"};
operatorString(strArray, (String str) -> {
String name = str.split(",")[0];
System.out.print("姓名:" + name);
}, (String str) -> {
int age = Integer.parseInt(str.split(",")[1]);
System.out.println(", 年龄:" + age);
});
//简化代码
operatorString(strArray, str -> System.out.print("姓名:" + str.split(",")[0]),
str -> System.out.println(", 年龄:" + Integer.parseInt(str.split(",")[1])));
}
private static void operatorString(String[] strArray, Consumer<String> con1, Consumer<String> con2) {
for (String str : strArray) {
con1.andThen(con2).accept(str);
}
}
}
5.Predicate接口
代码演示:
import java.util.function.Predicate;
public class PredicateDemo {
public static void main(String[] args) {
boolean result = checkString("hello", (String s) -> {
return s.length() > 6;
});
System.out.println(result);
//简写
boolean result2 = checkString("helloWorld", s -> s.length() > 6);
System.out.println(result2);
boolean result3 = checkString("hello", s -> s.length() > 6, s -> s.length() < 15);
System.out.println(result3);
boolean result4 = checkString("helloWorld", s -> s.length() > 6, s -> s.length() < 15);
System.out.println(result4);
boolean result5 = checkString2("hello", s -> s.length() > 6, s -> s.length() < 15);
System.out.println(result5);
boolean result6 = checkString2("helloWorld", s -> s.length() > 6, s -> s.length() < 15);
System.out.println(result6);
}
private static boolean checkString(String s, Predicate<String> p) {
// return p.test(s);
//否定操作
return p.negate().test(s);
}
//对同一个字符串给出不同的判断条件,最后把这两个判断的结果做逻辑与运算的结果作为最终的结果
private static boolean checkString(String s, Predicate<String> p1, Predicate<String> p2) {
// boolean b1 = p1.test(s);
// boolean b2 = p2.test(s);
// boolean b = b1 && b2;
// return b;
return p1.and(p2).test(s);
}
//对同一个字符串给出不同的判断条件,最后把这两个判断的结果做逻辑或运算的结果作为最终的结果
private static boolean checkString2(String s, Predicate<String> p1, Predicate<String> p2) {
// boolean b1 = p1.test(s);
// boolean b2 = p2.test(s);
// boolean b = b1 && b2;
// return b;
return p1.or(p2).test(s);
}
}
6.Predicate接口练习(筛选满足条件数据)
代码实现:
import java.util.ArrayList;
import java.util.function.Predicate;
public class PredicateTest {
public static void main(String[] args) {
String[] strArray = {"张三三,20", "王五,22", "李四四,40", "吕布布,55", "曾小贤,30"};
//调用方法,编写满足条件
// ArrayList<String> people = checkPeople(strArray, str -> {
// String name = str.split(",")[0];
// return name.length() > 2;
// }, str -> {
// int age = Integer.parseInt(str.split(",")[1]);
// return age > 33;
// });
//简写
ArrayList<String> people = checkPeople(strArray, str -> str.split(",")[0].length() > 2
, str -> Integer.parseInt(str.split(",")[1]) > 33);
//遍历集合
for (String s : people) {
System.out.println(s);
}
}
private static ArrayList<String> checkPeople(String[] strArray, Predicate<String> p1, Predicate<String> p2) {
//定义一个集合
ArrayList<String> array = new ArrayList<>();
//遍历数组,将满足条件的数据添加进入集合中
for (String str : strArray) {
if (p1.and(p2).test(str)) {
array.add(str);
}
}
return array;
}
}
7.Function接口
代码演示:
import java.util.function.Function;
public class FunctionDemo {
public static void main(String[] args) {
convert("100", s -> Integer.parseInt(s));
// convert("100", Integer::parseInt);//方法引用
convert(100, i -> String.valueOf(i + 10));
convert("100", s -> Integer.parseInt(s), i -> String.valueOf(i + 10));
}
//定义一个方法,把一个int类型的数据加上一个整数之后,转换为字符串在控制台输出
private static void convert(String s, Function<String, Integer> fun) {
// Integer i = fun.apply(s);
//自动拆箱
int i = fun.apply(s);
System.out.println(i);
}
//定义一个方法,把一个字符串转换为int类型的数据加上一个整数后,转换为字符串在控制台输出
private static void convert(int i, Function<Integer, String> fun) {
String s = fun.apply(i);
System.out.println(s);
}
//定义一个方法,把一个字符串转换为int类型,把int类型的数据加上一个整数之后,转换为字符串在控制台输出
private static void convert(String s, Function<String, Integer> fun1, Function<Integer, String> fun2) {
// Integer i = fun1.apply(s);
// String ss = fun2.apply(i);
// System.out.println(ss);
String ss = fun1.andThen(fun2).apply(s);
System.out.println(ss);
}
}
8.Function接口练习(按照指定要求操作数据)
代码实现:
import java.util.function.Function;
public class FunctionTest {
public static void main(String[] args) {
String s = "林小青,30";
convert(s, ss -> ss.split(",")[1], ss -> Integer.parseInt(ss), i -> i + 70);
}
private static void convert(String s, Function<String, String> fun1, Function<String, Integer> fun2, Function<Integer, Integer> fun3) {
//这里解释上面调用时 s和ss的混乱
// String ss = fun1.apply(s);
// Integer i = fun2.apply(ss);
// Integer i2 = fun3.apply(i);
int i2 = fun1.andThen(fun2).andThen(fun3).apply(s);
System.out.println(i2);
}
}