1、Lambda表达式概述
Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。
JDK 也提供了大量的内置函数式接口供我们使用,使得 Lambda 表达式的运用更加方便、高效。
1.2、函数式编程思想
1.2.1、概念
面向对象思想需要关注用什么对象完成什么事情、而函数式编程思想就类似于我们数学中的函数、它主要关注是对数据进行了什么操作
1.2.1、基本格式
(参数列表) -> {代码}
1.2.2、@FunctionalInterface
修饰函数式接口的,要求接口中的抽象方法只有一个。 这个注解往往会和 lambda 表达式一起出现。
1.3、函数式编程思想
/**
* @ClassName: Demo02
* @Author: VV
* @Version: 1.0.0
* @Description: TODO
* @MyEmail: vv1213418894@163.com
* @CreateTime: 2022-09-30 10:55:52
*/
public class Demo02 {
/** 多参数、无返回值 **/
@FunctionalInterface
public interface NoReturnMutiparam{
void method(int a,int b);
}
/** 无参数、无返回值 **/
@FunctionalInterface
public interface NoReturnNoparam{
void method();
}
/** 一个参数、无返回值 **/
@FunctionalInterface
public interface NoReturnOneparam{
void method(int a);
}
/** 多个参数、有返回值 **/
@FunctionalInterface
public interface ReturnMultiparam{
int method(int a,int b);
}
/** 无参数、有返回值 **/
@FunctionalInterface
public interface ReturnNoparam{
int method();
}
/** 一个参数、有返回值 **/
@FunctionalInterface
public interface ReturnOneparam{
int method(int a);
}
}
public static void main(String[] args) {
/** 多参数、无返回值 **/
Demo02.NoReturnMutiparam noReturnMutiparam = (a,b) ->{
System.out.println(a + " " + b);
};
noReturnMutiparam.method(1,2);
/** 无参数、无返回值 **/
Demo02.NoReturnNoparam noReturnNoparam = () -> {
System.out.println("");
};
noReturnNoparam.method();
/** 一个参数、无返回值 **/
Demo02.NoReturnOneparam noReturnOneparam = (a) -> {
System.out.println(a + " ");
};
noReturnOneparam.method(0);
/** 多个参数、有返回值 **/
Demo02.ReturnMultiparam returnMultiparam = (a,b) -> {
return 0;
};
returnMultiparam.method(1,2);
/** 无参数、有返回值 **/
Demo02.ReturnNoparam returnNoparam= () -> {
return 0;
};
returnNoparam.method();
/** 一个参数、有返回值 **/
Demo02.ReturnOneparam returnOneparam = (a) -> {
return 0;
};
returnOneparam.method(0);
}
1.3.1、Java内置四大核心函数式接口
/**
* @ClassName: TestLambda3
* @Author: VV
* @Version: 1.0.0
* @Description: 1、Consumer<T> 消费型接口
* void accept(T t);
* 2、Supplier<T> 供给型接口
* T get();
* 3、Function<T,R> 函数型接口
* R apply(T t);
* 4、Predicate<T> 断言型接口
* boolean test(T t);
* @MyEmail: vv1213418894@163.com
* @CreateTime: 2022-10-03 21:19:02
*/
public class TestLambda3 {
// Consumer<T> 消费型接口:
@Test
public void test1(){
happy(10000,(m) -> System.out.println(""+ m));
}
public void happy(double money, Consumer<Double> con){
con.accept(money);
}
// Supplier<T> 供给型接口:
@Test
public void test2(){
getNumList(10,() -> (int)(Math.random() * 10));
}
public List<Integer> getNumList(int num, Supplier<Integer> sup){
List<Integer> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
Integer integer = sup.get();
list.add(integer);
}
return list;
}
// Function<T,R> 函数型接口
@Test
public void test3(){
String newStr = strHandler(" 11 ",(str) -> str.trim());
}
public String strHandler(String str, Function<String,String> function){
return function.apply(str);
}
// Predicate<T> 断言型接口:
@Test
public void test4(){
List<String> str = Arrays.asList("1", "4548", "47854", "dwr");
filterStr(str,(e) -> e.length() > 3);
}
public List<String> filterStr(List<String> list, Predicate<String> pre){
List<String> strList = new ArrayList<>();
for(String str:list){
if(pre.test(str)){
strList.add(str);
}
}
return strList;
}
}
1.3.2、lambda练习
查询雇员信息、年龄及名称比较
List<Employee> list = Arrays.asList(
new Employee("张三", 18, 99.99),
new Employee("李四", 38, 99.99),
new Employee("王五", 50, 99.99),
new Employee("赵六", 16, 99.99),
new Employee("田七", 8, 99.99)
);
@Test
public void test01(){
Collections.sort(list,(e1,e2) ->{
if(e1.getAge() == e2.getAge()){
return e1.getName().compareTo(e2.getName());
}else {
return Integer.compare(e1.getAge(),e2.getAge());
}
});
for (Employee e:list){
System.out.println(e);
}
}
字符串大写
/**
* @InterfaceName: MyFunction
* @Author: VV
* @Version: 1.0.0
* @Description: TODO
* @MyEmail: vv1213418894@163.com
* @CreateTime: 2022-10-02 18:03:25
*/
@FunctionalInterface
public interface MyFunction {
public String getValue(String str);
}
@Test
public void test02(){
String asd = strHandler("asd", (str) -> {
return str.toUpperCase();
});
}
public String strHandler(String str,MyFunction myFunction){
return myFunction.getValue(str);
}
两数相加
@FunctionalInterface
public interface MyFunction2<T,R> {
public R sumInt(T t1,T t2);
}
@Test
public void test03(){
sumInt(1,2,(x,y) -> x + y);
}
public void sumInt(int t1,int t2,MyFunction2<Integer,Integer> myFunction2){
System.out.println(myFunction2.sumInt(t1,t2));
}
1.4、Stream的使用
Java8中有两个最为重要的改变、第一个是Lambda表达式、另外一个则是StreamAPI
Stream是Java8中处理集合的关键抽象概念、可以指定你希望对集合进行的操作、可以执行非常复杂的查找、过滤和映射数据等操作。
使用StreamApi对集合数据进行操作、类似于使用SQL执行的数据库查询、也可以使用StreamAPI来进行并行操作。
1.4.1、Stream的创建
@Test
public void test01(){
// 1、可以通过Collection 系列集合提供Stream() 或 paralleStream()
ArrayList<String> list = new ArrayList<>();
// 2、通过Arrays中静态方法stream()获取数据流
Employee[] emps = new Employee[10];
Stream<Employee> stream = Arrays.stream(emps);
// 3、通过Stream类中的静态方法
Stream<String> aa = Stream.of("aa", "bb", "cc");
// 4、创建无限流
Stream<Integer> iterate = Stream.iterate(0, (x) -> x + 2);
iterate.limit(10).forEach(System.out::println);
}
基本API操作
@Test
public void test01(){
List<Employee> list = Arrays.asList(
new Employee("张三", 18, 99.99),
new Employee("李四", 38, 99.99),
new Employee("王五", 50, 99.99),
new Employee("赵六", 16, 99.99),
new Employee("田七", 8, 99.99)
);
Stream<Employee> employeeStream = list.stream().filter(e -> e.getAge() > 15);
Stream<Employee> limit = list.stream().limit(2);
Stream<Employee> distinct = list.stream().skip(2).distinct();
}