JDK8新特性入门到精通

文章目录

          • 一、 接口中默认方法修饰为普通方法
            • 1. 在jdk8之前
            • 2. 在JDK 1.8开始
            • 3. 案例演练
          • 二、Lambda表达式
            • 2.1. 什么是Lambda表达式
            • 2.2. 为什么要使用Lambda表达式
            • 2.3. Lambda表达式的规范
            • 2.4. 函数接口定义
            • 2.5. Lambda基础语法
            • 2.6. 方法引入
            • 2.7. Lambda实战案例
          • 三、java 8 stream流
            • 3.1. 什么是stream流
            • 3.2. Stream创建方式
            • 3.3. Stream将list转换为Set
            • 3.4. Stream将list集合转换成map
            • 3.5. Stream将Reduce 求和
            • 3.6. Stream查找最大值和最小值
            • 3.7. Stream Match用法
            • 3.8. Stream For循环
            • 3.9. Stream filter过滤器
            • 3.10. Stream排序 sorted
            • 3.11. Stream limit和skip
            • 3.11. Stream综合案例
            • 3.12. Stream并行流与串行流区别
          • 四、JDK8Optional
            • 4.1. 判断参数是否为空
            • 4.2. 参数为空可以设定默认值
            • 4.3. 参数实现过滤
          • 五、lambda 搭配使用
            • 5.1. 优化方案1
            • 5.2. 优化方案2
            • 5.3. 优化方案3
          • 六、归纳梳理
            • 6.1. 经验分享
            • 6.2. 练习案例汇总

一、 接口中默认方法修饰为普通方法
1. 在jdk8之前

interface之中可以定义变量和方法,变量必须是public、static、final的,方法必须是public、abstract的,由于这些修饰符都是默认的。

接口定义方法:public 抽象方法 需要子类实现
接口定义变量:public、static、final

2. 在JDK 1.8开始

支持使用static和default 修饰 可以写方法体,不需要子类重写。
方法:
普通方法 可以有方法体
抽象方法 没有方法体需要子类实现 重写。

3. 案例演练
public interface JDK8Interface {void addOrder();default void getDefaultOrder(){System.out.println("我是默认方法");}static void getStaticOrder(){System.out.println("我是静态方法");}
}public class JDK8InterfaceImpl implements JDK8Interface {@Overridepublic void addOrder() {System.out.println("addOrder");}
}
二、Lambda表达式
2.1. 什么是Lambda表达式

LAMBADA 好处: 简化我们匿名内部类的调用。
Lambda+方法引入 代码变得更加精简。

2.2. 为什么要使用Lambda表达式

可以非常简洁的形式调用我们的匿名函数接口。

// 使用lambda调用有参函数
@FunctionalInterface
public interface CarryParamInterface {String carryParam(int i, int j);
}
    @Testpublic void lambdaCarryParamTest() {// 1.使用匿名内部类调用有参数函数方法// String result = new CarryParamInterface() {//     @Override//     public String carryParam(int i, int j) {//         return i + "-" + j;//     }// }.carryParam(1, 1);// System.out.println(result);//2.lambda 精简写法优化//如果方法体只有一条return的情况下不需要些{}return// CarryParamInterface carryParamInterface = (a, b) -> a + "-" + b;// System.out.println(carryParamInterface.carryParam(2, 6));//3.lambda 精简写法优化((CarryParamInterface) (a, b) -> a + "-" + b).carryParam(1, 2);System.out.println(((CarryParamInterface) (a, b) -> a + "-" + b).carryParam(1, 2));}
2.3. Lambda表达式的规范

使用Lambda表达式 依赖于函数接口

  1. 在接口中只能够允许有一个抽象方法
  2. 在函数接口中定义object类中方法
  3. 使用默认或者静态方法
  4. @FunctionalInterface 表示该接口为函数接口

Java中使用Lambda表达式的规范,必须是为函数接口
函数接口的定义:在该接口中只能存在一个抽象方法,该接口称作为函数接口

JDK中自带的函数接口:
java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener我们也可以使用@FunctionalInterface修饰为函数接口
2.4. 函数接口定义
//使用lambda调用无参函数
@FunctionalInterface
public interface NoParamInterface {void get();
}
// 使用lambda调用有参函数
@FunctionalInterface
public interface CarryParamInterface {String carryParam(int i, int j);
}
2.5. Lambda基础语法
()---参数列表-> 分隔
{}   方法体
(a,b)->{
}无参方法调用
带参数方法调用(函数接口的参数列表 不需要写类型 需要定义参数名称)->{方法体}():函数方法参数列表
->分隔 {}方法体
(a,b)->{
Sout(a,b)
}Lambda语法:
():参数列表
->分隔
{}:方法体
()->{}

无参方法调用

//使用lambda调用无参函数
@FunctionalInterface
public interface NoParamInterface {void get();
}
   //使用lambda调用无参函数@Testpublic void lambdaNoParamTest() {//lambda无参数调用//精简写法1: 如果方法体中只有一条语句的情况下 可以不需要写{}// NoParamInterface noParamInterface = () -> System.out.println("lambda无参数调用->精简写法1");// noParamInterface.get();//精简写法2((NoParamInterface) () -> System.out.println("lambda无参数调用->精简写法2")).get();}
// 使用lambda调用有参函数
@FunctionalInterface
public interface CarryParamInterface {String carryParam(int i, int j);
}
 // 使用lambda调用有参函数@Testpublic void lambdaCarryParamTest() {// 1.使用匿名内部类调用有参数函数方法// String result = new CarryParamInterface() {//     @Override//     public String carryParam(int i, int j) {//         return i + "-" + j;//     }// }.carryParam(1, 1);// System.out.println(result);//2.lambda 精简写法优化//如果方法体只有一条return的情况下不需要些{}return// CarryParamInterface carryParamInterface = (a, b) -> a + "-" + b;// System.out.println(carryParamInterface.carryParam(2, 6));//3.lambda 精简写法优化((CarryParamInterface) (a, b) -> a + "-" + b).carryParam(1, 2);System.out.println(((CarryParamInterface) (a, b) -> a + "-" + b).carryParam(1, 2));}
2.6. 方法引入

方法引入实际上就是lambda表达式中直接引入的方法。

必须遵循规范:引入的方法参数列表返回类型必须要和函数接口参数列表、返回
类型保持一致。

  • 静态方法引入
@FunctionalInterface
public interface MessageInterface {void get(Integer i);
}public class MethodReference {//静态方法引入public static void getStaticMethod(Integer i) {System.out.println("我是静态方法");}
}
    //静态方法引入@Testpublic void staticMethodInto() {// 1.使用匿名内部类的形式 调用get方法// new MessageInterface() {//     @Override//     public void get(Integer i) {//         MethodReference.getStaticMethod(i);//     }// }.get(1);//2.lambda 形式// MessageInterface messageInterface = (i) -> {//     MethodReference.getStaticMethod(i);// };// messageInterface.get(2);//处理逻辑只有一行大括号可以省略// MessageInterface messageInterface = (i) -> MethodReference.getStaticMethod(i);// messageInterface.get(2);//3.使用方法引入,必须满足方法引入的方法必须和函数中的方法参数列表和返回值保持一致// MessageInterface messageInterface = MethodReference::getStaticMethod;// messageInterface.get(2);/*** 分析* (i) -> MethodReference.getStaticMethod(i) 等于 MethodReference::getStaticMethod* lambda 使用方法引入,要求:必须满足方法引入的方法必须和函数中的方法参数列表和返回值保持一致*///精简写法((MessageInterface) MethodReference::getStaticMethod).get(2);}

-实例方法引入

@FunctionalInterface
public interface MessageInterface2 {String getMessage();
}
public class MethodInto {
//实例方法引入@Testpublic void exampleMethodInto() {// MethodInto methodInto = new MethodInto();// MessageInterface2 messageInterface2 = () -> methodInto.objGet();// System.out.println(messageInterface2.getMessage());MethodInto methodInto = new MethodInto();MessageInterface2 messageInterface2 = methodInto::objGet;System.out.println(messageInterface2.getMessage());}//实例对昂方法public String objGet() {return "1111111";}
}
  • 构造函数引入
@FunctionalInterface
public interface UserInterface {User getUser();
}//构造函数引入@Testpublic void functionMethodInto() {// UserInterface userInterface = () -> {//     return new User();// };UserInterface userInterface = User::new;System.out.println(userInterface.getUser());}
  • 对象方法引入
@FunctionalInterface
public interface LyService {String get(ObjMethodInto objMethodInto);
}
public class ObjMethodInto {//对象方法引入public static void main(String[] args) {//1.使用匿名内部类形式// LyService lyService = new LyService() {//     @Override//     public String get(ObjMethodInto objMethodInto) {//         return objMethodInto.objGet();//     }// };// System.out.println(lyService.get(new ObjMethodInto()));//2.lambda// LyService lyService = (objMethodInto) -> objMethodInto.objGet();// System.out.println(lyService.get(new ObjMethodInto()));//3.对象方法引入// LyService lyService = ObjMethodInto::objGet;// System.out.println(lyService.get(new ObjMethodInto()));/*** 分析* ObjMethodInto::objGet 等同于 (objMethodInto) -> objMethodInto.objGet()*///    案例//    需要将string类型的字符串获取长度// Function<String, Integer> stringIntegerFunction = (str)->str.length();// System.out.println(stringIntegerFunction.apply("gblfy"));Function<String, Integer> stringIntegerFunction = String::length;System.out.println(stringIntegerFunction.apply("gblfy"));}//实例对昂方法public String objGet() {return "1111111";}
}
2.7. Lambda实战案例

Foreach

    //lambda实现集合遍历@Testpublic void dataErgodic() {//案例:lambda实现集合遍历List<String> list = new ArrayList<>();list.add("gblfy.com");list.add("gblfy.com2");list.add("gblfy.com3");//1.普通写法// list.forEach(new Consumer<String>() {//     @Override//     public void accept(String s) {//         System.out.println(s);//     }// });//2.lambda精简写法list.forEach(p -> System.out.println(p));}

Lambda集合排序

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@EqualsAndHashCode
public class User {private String name;private int age;
}
  //Lambda集合排序@Testpublic void lambdaSort(){List<User> list = userList();list.sort((u1,u2)-> u1.getAge()-u2.getAge());}//测试集合数据public List<User> userList() {List<User> list = new ArrayList<>();list.add(new User("yuxin", 5));list.add(new User("yuze", 2));list.add(new User("ly", 22));list.add(new User("zz", 15));list.add(new User("gb", 22));list.add(new User("gb", 20));list.add(new User("gb", 25));list.add(new User("gb", 26));list.add(new User("gb", 28));list.add(new User("gb", 27));return list;}
  • 线程调用
// lambda实现线程调用@Testpublic void lambdaThread() {//1.匿名内部类调用线程// new Thread(new Runnable() {//     @Override//     public void run() {//         System.out.println("匿名内部类调用线程");//     }// }).start();//2.lambda调用线程new Thread(() -> System.out.println("lambda调用线程")).start();}
三、java 8 stream流
3.1. 什么是stream流

Stream 是JDK1.8 中处理集合的关键抽象概念,Lambda 和 Stream 是JDK1.8新增的函数式编程最有亮点的特性了,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

Stream :非常方便精简的形式遍历集合实现 过滤、排序等。

Mysql:select userName from mayikt where userName =‘mayikt’
Order by age limt(0,2)

在这里插入图片描述

3.2. Stream创建方式

parallelStream为并行流采用多线程执行
Stream采用单线程执行
parallelStream效率比Stream要高。

//Stream创建方式@Testpublic void lambdaStream(){List<User> list = new ArrayList<>();list.add(new User("yuxin", 5));list.add(new User("yuze", 2));list.add(new User("ly", 22));list.add(new User("zz", 15));list.add(new User("gb", 22));list.add(new User("gb", 20));list.add(new User("gb", 25));list.add(new User("gb", 26));list.add(new User("gb", 28));list.add(new User("gb", 27));list.stream();list.parallelStream();}
3.3. Stream将list转换为Set
  // stream将list集合转换为set@Testpublic void streamListToSet() {List<User> list = userList();/*** 创建stream流* parallelStream为并行流采用多线程执行* Stream采用单线程执行* parallelStream效率比Stream要高*///将集合转化为set,然后,进行循环遍历list.stream().collect(Collectors.toSet()).forEach(p -> System.out.println(p));}
3.4. Stream将list集合转换成map
   // stream将list集合转换成map@Testpublic void streamListToMap() {List<User> list = userList();//list 集合只有元素 key list转换成map集成的想境况下 指定key-->User对象中的username属性 value User对象//new Function<User(value map), String(key map)>   map函数形式为Map<String,User>//lambda写法// list.stream().collect(Collectors.toMap(new Function<User, String>() {//     //这里指的是map中的key用list中的name//     @Override//     public String apply(User user) {//         return user.getName();//     }// }, new Function<User, User>() {//     //这里指的是map中的value用list中的User对象//     @Override//     public User apply(User user) {//         return user;//     }// })).forEach(new BiConsumer<String, User>() {//     //这里的forEach只是为了看效果,遍历map中的key和value,如果没有遍历请求可以不做forEach//     @Override//     public void accept(String key, User user) {//         System.out.println(key + "," + user);//     }// });//简写形式,如果不熟练建议使用idea辅助生成简写形式list.stream().collect(Collectors.toMap(user -> user.getName(), user -> user)).forEach((key, user) -> System.out.println(key + "," + user));}
3.5. Stream将Reduce 求和
    // stream计算求和@Testpublic void streamSum() {// Integer sum = Stream.of(10, 12, 8, 15, 20).reduce(new BinaryOperator<Integer>() {//     @Override//     public Integer apply(Integer integer, Integer integer2) {//         return integer + integer2;//     }// }).get();// Integer sum = Stream.of(10, 12, 8, 15, 20).reduce((i1, i2) -> i1 + i2).get();// System.out.println(sum);//    案例List<User> list = userList();// User u = list.stream().reduce(new BinaryOperator<User>() {//     //这里返回值User对象,因此,new User实例返回,如果是数字的话可以直接返回//     @Override//     public User apply(User user, User user2) {//         return new User("sum", user.getAge() + user2.getAge());//     }// }).get();//这里返回值User对象,因此,new User实例返回,如果是数字的话可以直接返回//简写User u = list.stream().reduce((u1, u2) -> new User("sum", u1.getAge() + u2.getAge())).get();System.out.println(u);System.out.println("age sum->" + u.getAge());}
3.6. Stream查找最大值和最小值
    // stream查找最大值和最小值@Testpublic void streamFindMaxAndMin() {List<User> list = userList();// User user = list.stream().max(new Comparator<User>() {//     @Override//     public int compare(User o1, User o2) {//         return o1.getAge() - o2.getAge();//     }// }).get();// User user = list.stream().max((u1, u2) -> u1.getAge() - u2.getAge()).get();// System.out.println("max age->" + user.getAge());User user = list.stream().min((o1, o2) -> o1.getAge() - o2.getAge()).get();System.out.println("min age->" + user.getAge());}
3.7. Stream Match用法

anyMatch表示,判断的条件里,任意一个元素成功,返回true
allMatch表示,判断条件里的元素,所有的都是,返回true
noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true

  // stream的Match用法@Testpublic void streamMatch() {List<User> list = userList();//    匹配任意一个就返回true// boolean b = list.stream().anyMatch(user -> "ly".equals(user.getName()));// System.out.println("test anyMatch->" + b);//    全部匹配就返回trueboolean b = list.stream().allMatch(user -> "ly".equals(user.getName()));System.out.println("test allMatch->" + b);}
3.8. Stream For循环
   // stream For循环@Testpublic void streamFor() {List<User> list = userList();list.stream().forEach(u-> System.out.println(u));}
3.9. Stream filter过滤器
    // stream过滤器的用法@Testpublic void streamFilter() {List<User> list = userList();// list.stream().filter(user -> {//     //过滤username等于gb//     // return USER_NAME.equals(user.getName());////     //过滤username等于gb并且年龄大于20//     return USER_NAME.equals(user.getName()) && user.getAge() > 20;// }).forEach(u -> System.out.println(u));//lambda简写list.stream().filter(user -> USER_NAME.equals(user.getName())).forEach(u -> System.out.println(u));list.stream().filter(user -> USER_NAME.equals(user.getName()) && user.getAge() > 20).forEach(u -> System.out.println(u));}
3.10. Stream排序 sorted
    //stream实现对数据排序@Testpublic void dataSort() {List<User> list = userList();// list.sort(new Comparator<User>() {//     @Override//     public int compare(User o1, User o2) {//         //默认正序排列//         // return o1.getAge() - o2.getAge();//         //倒序排列//         return o2.getAge() - o1.getAge();////     }// });//正序排序从小到大// list.stream().sorted((u1, u2) -> u1.getAge() - u2.getAge()).forEach(user -> System.out.println(user));//倒序排序从大到小list.stream().sorted((u1, u2) -> u2.getAge() - u1.getAge()).forEach(user -> System.out.println(user));}
3.11. Stream limit和skip
    // stream  skip limit用法@Testpublic void streamLimit() {List<User> list = userList();//取集合的前2条数据// list.stream().limit(2).forEach(u -> System.out.println(u));//    跳过前2条,从第3条开始取,取2条// list.stream().skip(2).limit(2).forEach(u -> System.out.println(u));// 从头取3条数据,跳过前2条,那么只会剩余一条数据list.stream().limit(3).skip(2).forEach(u -> System.out.println(u));}
3.11. Stream综合案例
    /*** stream 综合案例* 要求* 1.用户信息按照年领倒序* 2.用户数据中包含gb* 3.从用户信息组去前2名*/@Testpublic void streamMultipleCase() {List<User> list = userList();//1.用户信息按照年领倒序list.stream().sorted((u1, u2) -> u2.getAge() - u1.getAge())//2.用户数据中包含gb.filter(user -> USER_NAME.equals(user.getName()))//3.从用户信息组去前2名.limit(2).forEach(user -> System.out.println(user));}
3.12. Stream并行流与串行流区别

串行流:单线程的方式操作; 数据量比较少的时候。
并行流:多线程方式操作;数据量比较大的时候,原理:
Fork join 将一个大的任务拆分n多个小的子任务并行执行,
最后在统计结果,有可能会非常消耗cpu的资源,确实可以
提高效率。

注意:数据量比较少的情况下,不要使用并行流。

四、JDK8Optional

Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常。

4.1. 判断参数是否为空
//判断参数是否为空//说明:空字符串不为null@Testpublic void isNull() {/*** ofNullable(可以传递一个空对象)* Of(不可以传递空对象)*/String username = "gbl";// String username = "";// String username = null;Optional<String> optional = Optional.ofNullable(username);// Optional<String> optional = Optional.of(username);boolean present = optional.isPresent();if (present) {System.out.println("username不为空");}}
4.2. 参数为空可以设定默认值
   //参数为空可以设定默认值@Testpublic void isNullSetDefault() {// String username = null;String username = "gbl";String optional = Optional.ofNullable(username).orElse("123456");System.out.println(optional);}
4.3. 参数实现过滤
    //参数实现过滤@Testpublic void paramFilter() {String username = null;boolean present = Optional.ofNullable(username).filter(p -> USER_NAME.equals(p)).isPresent();System.out.println(present);}
五、lambda 搭配使用

与Lambda表达式结合使用,优化代码

5.1. 优化方案1
//与Lambda表达式结合使用,优化代码@Testpublic void ifPresent() {String username = null;//优化前if (username != null) {System.out.println(username);}//优化后//lambda 简写形式// Optional.ofNullable(username).ifPresent(s -> System.out.println(s));//方法引入 简写形式Optional.ofNullable(username).ifPresent(System.out::print);}
5.2. 优化方案2
import java.util.Optional;
import java.util.function.Supplier;public class Test01 {private static User user = null;public static void main(String[] args) {User user = Test01.getUser();System.out.println(user);}public static User getUser() {// 优化前// if (user == null) {//     return createUser();// }// return user;//第1种:这种处理方案适用于只有一步操作,在此案例中会出现user全局对象为null的场景// return Optional.ofNullable(user).orElse(createUser());//第2种:这种方案适用于符合逻辑之前做预处理的一些操作,可解决第一种全局user对象为空// return Optional.ofNullable(user).orElseGet(() -> {//     user = createUser();//     return user;// });//第3种:方法引入return Optional.ofNullable(user).orElseGet(Test01::createUser);}private static User createUser() {return new User("123456", 2);}
}
5.3. 优化方案3

map中获取的返回值自动被Optional包装,即返回值 -> Optional<返回值>

flatMap中返回值保持不变,但必须是Optional类型,即Optional<返回值> -> Optional<返回值>

package com.gblfy.elk.lambda;import com.gblfy.elk.entity.User;import java.util.Optional;public class Test02 {public static void main(String[] args) {String orderName = Test02.getOrderName();System.out.println(orderName);}public static String getOrderName() {// 优化前写法:User user = new User("GBLFY.COM", 10);//1.先判断user对象是否为null// if (user != null) {//2.user对象不为null,则获取username//     String userName = user.getName()//3.username不为null,转小写//     if (userName != null) {//         return userName.toLowerCase();//     }// }// Optional<User> userOptional1 = Optional.ofNullable(user);// Optional<String> optional = userOptional1.map(u -> u.getName());// Optional<String> toLowerCase = optional.map(name -> name.toLowerCase());// return toLowerCase.get();return//1.先判断user对象是否为nullOptional.ofNullable(user)//2.user对象不为null,则获取username.map(u -> u.getName())//3.username不为null,转小写,为null返回null.map(un -> un.toLowerCase()).orElse(null);}
}
六、归纳梳理
6.1. 经验分享

1.lambda使用必须为函数接口,需要@FunctionalInterface注解修饰,并且只能有一个抽象方法。(object父类先不计数)
2.lambda只是对内部类的的写法简写代码,使用咱们操作内部类方便许多
3.lambda stream 提高了咱们对数据的效率(循环遍历、判断、list与set与map之间的转换、排序、分页->取数据前几条、跳过指定条数的数据等等),但是,使用时要对中间操作和终止操作,要分清,一旦用了终止操作就无法在使用中间操作。
4.方法引入4种,这个需要认真理解,4种方法引入的区别和使用场景,勤加练习,熟能生巧。
5.普通代码转换lambda不熟练时,前期可以先利用idea辅助,使用stream进行操作数据或者重构代码时,建议先把普通代码的逻辑实现的流程写下来,然后再按照流程,一步一步优化重构,刚开始不要求快,按照此思路勤加练习,养成这样的习惯,慢慢的就会提升你重构代码的能力,我就是这样做的,好了,分享就到这吧!小伙伴们,我们一起加油!

6.2. 练习案例汇总

User对象

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@EqualsAndHashCode
public class User {private String name;private int age;
}

无参接口

//使用lambda调用无参函数
@FunctionalInterface
public interface NoParamInterface {void get();
}

有参接口

// 使用lambda调用有参函数
@FunctionalInterface
public interface CarryParamInterface {String carryParam(int i, int j);
}

lambda案例

package com.gblfy.lambda;import com.gblfy.elk.entity.User;
import com.gblfy.elk.lambda.CarryParamInterface;
import com.gblfy.elk.lambda.NoParamInterface;
import org.junit.Test;import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.OptionalLong;
import java.util.stream.Collectors;
import java.util.stream.LongStream;public class LambdaCase {public static final String USER_NAME = "gb";//使用lambda调用无参函数@Testpublic void lambdaNoParamTest() {//lambda无参数调用//精简写法1: 如果方法体中只有一条语句的情况下 可以不需要写{}// NoParamInterface noParamInterface = () -> System.out.println("lambda无参数调用->精简写法1");// noParamInterface.get();//精简写法2((NoParamInterface) () -> System.out.println("lambda无参数调用->精简写法2")).get();}// 使用lambda调用有参函数@Testpublic void lambdaCarryParamTest() {// 1.使用匿名内部类调用有参数函数方法// String result = new CarryParamInterface() {//     @Override//     public String carryParam(int i, int j) {//         return i + "-" + j;//     }// }.carryParam(1, 1);// System.out.println(result);//2.lambda 精简写法优化//如果方法体只有一条return的情况下不需要些{}return// CarryParamInterface carryParamInterface = (a, b) -> a + "-" + b;// System.out.println(carryParamInterface.carryParam(2, 6));//3.lambda 精简写法优化((CarryParamInterface) (a, b) -> a + "-" + b).carryParam(1, 2);System.out.println(((CarryParamInterface) (a, b) -> a + "-" + b).carryParam(1, 2));}//测试集合数据public List<User> userList() {List<User> list = new ArrayList<>();list.add(new User("yuxin", 5));list.add(new User("yuze", 2));list.add(new User("ly", 22));list.add(new User("zz", 15));list.add(new User("gb", 22));list.add(new User("gb", 20));list.add(new User("gb", 25));list.add(new User("gb", 26));list.add(new User("gb", 28));list.add(new User("gb", 27));return list;}//lambda实现集合遍历@Testpublic void dataErgodic() {//案例:lambda实现集合遍历List<String> list = new ArrayList<>();list.add("gblfy.com");list.add("gblfy.com2");list.add("gblfy.com3");//1.普通写法// list.forEach(new Consumer<String>() {//     @Override//     public void accept(String s) {//         System.out.println(s);//     }// });//2.lambda精简写法list.forEach(p -> System.out.println(p));}//Lambda集合排序@Testpublic void lambdaSort(){List<User> list = userList();list.sort((u1,u2)-> u1.getAge()-u2.getAge());}// lambda实现线程调用@Testpublic void lambdaThread() {//1.匿名内部类调用线程// new Thread(new Runnable() {//     @Override//     public void run() {//         System.out.println("匿名内部类调用线程");//     }// }).start();//2.lambda调用线程new Thread(() -> System.out.println("lambda调用线程")).start();}//Stream创建方式@Testpublic void lambdaStream(){List<User> list = new ArrayList<>();list.add(new User("yuxin", 5));list.add(new User("yuze", 2));list.add(new User("ly", 22));list.add(new User("zz", 15));list.add(new User("gb", 22));list.add(new User("gb", 20));list.add(new User("gb", 25));list.add(new User("gb", 26));list.add(new User("gb", 28));list.add(new User("gb", 27));list.stream();list.parallelStream();}// stream将list集合转换为set@Testpublic void streamListToSet() {List<User> list = userList();/*** 创建stream流* parallelStream为并行流采用多线程执行* Stream采用单线程执行* parallelStream效率比Stream要高*///将集合转化为set,然后,进行循环遍历list.stream().collect(Collectors.toSet()).forEach(p -> System.out.println(p));}// stream将list集合转换成map@Testpublic void streamListToMap() {List<User> list = userList();//list 集合只有元素 key list转换成map集成的想境况下 指定key-->User对象中的username属性 value User对象//new Function<User(value map), String(key map)>   map函数形式为Map<String,User>//lambda写法// list.stream().collect(Collectors.toMap(new Function<User, String>() {//     //这里指的是map中的key用list中的name//     @Override//     public String apply(User user) {//         return user.getName();//     }// }, new Function<User, User>() {//     //这里指的是map中的value用list中的User对象//     @Override//     public User apply(User user) {//         return user;//     }// })).forEach(new BiConsumer<String, User>() {//     //这里的forEach只是为了看效果,遍历map中的key和value,如果没有遍历请求可以不做forEach//     @Override//     public void accept(String key, User user) {//         System.out.println(key + "," + user);//     }// });//简写形式,如果不熟练建议使用idea辅助生成简写形式list.stream().collect(Collectors.toMap(user -> user.getName(), user -> user)).forEach((key, user) -> System.out.println(key + "," + user));}// stream计算求和@Testpublic void streamSum() {// Integer sum = Stream.of(10, 12, 8, 15, 20).reduce(new BinaryOperator<Integer>() {//     @Override//     public Integer apply(Integer integer, Integer integer2) {//         return integer + integer2;//     }// }).get();// Integer sum = Stream.of(10, 12, 8, 15, 20).reduce((i1, i2) -> i1 + i2).get();// System.out.println(sum);//    案例List<User> list = userList();// User u = list.stream().reduce(new BinaryOperator<User>() {//     //这里返回值User对象,因此,new User实例返回,如果是数字的话可以直接返回//     @Override//     public User apply(User user, User user2) {//         return new User("sum", user.getAge() + user2.getAge());//     }// }).get();//这里返回值User对象,因此,new User实例返回,如果是数字的话可以直接返回//简写User u = list.stream().reduce((u1, u2) -> new User("sum", u1.getAge() + u2.getAge())).get();System.out.println(u);System.out.println("age sum->" + u.getAge());}// stream查找最大值和最小值@Testpublic void streamFindMaxAndMin() {List<User> list = userList();// User user = list.stream().max(new Comparator<User>() {//     @Override//     public int compare(User o1, User o2) {//         return o1.getAge() - o2.getAge();//     }// }).get();// User user = list.stream().max((u1, u2) -> u1.getAge() - u2.getAge()).get();// System.out.println("max age->" + user.getAge());User user = list.stream().min((o1, o2) -> o1.getAge() - o2.getAge()).get();System.out.println("min age->" + user.getAge());}// stream的Match用法@Testpublic void streamMatch() {List<User> list = userList();//    匹配任意一个就返回true// boolean b = list.stream().anyMatch(user -> "ly".equals(user.getName()));// System.out.println("test anyMatch->" + b);//    全部匹配就返回trueboolean b = list.stream().allMatch(user -> "ly".equals(user.getName()));System.out.println("test allMatch->" + b);}// stream For循环@Testpublic void streamFor() {List<User> list = userList();list.stream().forEach(u-> System.out.println(u));}// stream过滤器的用法@Testpublic void streamFilter() {List<User> list = userList();// list.stream().filter(user -> {//     //过滤username等于gb//     // return USER_NAME.equals(user.getName());////     //过滤username等于gb并且年龄大于20//     return USER_NAME.equals(user.getName()) && user.getAge() > 20;// }).forEach(u -> System.out.println(u));//lambda简写list.stream().filter(user -> USER_NAME.equals(user.getName())).forEach(u -> System.out.println(u));list.stream().filter(user -> USER_NAME.equals(user.getName()) && user.getAge() > 20).forEach(u -> System.out.println(u));}// stream  skip limit用法@Testpublic void streamLimit() {List<User> list = userList();//取集合的前2条数据// list.stream().limit(2).forEach(u -> System.out.println(u));//    跳过前2条,从第3条开始取,取2条// list.stream().skip(2).limit(2).forEach(u -> System.out.println(u));// 从头取3条数据,跳过前2条,那么只会剩余一条数据list.stream().limit(3).skip(2).forEach(u -> System.out.println(u));}//stream实现对数据排序@Testpublic void dataSort() {List<User> list = userList();// list.sort(new Comparator<User>() {//     @Override//     public int compare(User o1, User o2) {//         //默认正序排列//         // return o1.getAge() - o2.getAge();//         //倒序排列//         return o2.getAge() - o1.getAge();////     }// });//正序排序从小到大// list.stream().sorted((u1, u2) -> u1.getAge() - u2.getAge()).forEach(user -> System.out.println(user));//倒序排序从大到小list.stream().sorted((u1, u2) -> u2.getAge() - u1.getAge()).forEach(user -> System.out.println(user));}/*** stream 综合案例* 要求* 1.用户信息按照年领倒序* 2.用户数据中包含gb* 3.从用户信息组去前2名*/@Testpublic void streamMultipleCase() {List<User> list = userList();//1.用户信息按照年领倒序list.stream().sorted((u1, u2) -> u2.getAge() - u1.getAge())//2.用户数据中包含gb.filter(user -> USER_NAME.equals(user.getName()))//3.从用户信息组去前2名.limit(2).forEach(user -> System.out.println(user));}//    并行流底层实现原理@Testpublic void streamSingleThread() {Instant start = Instant.now();long sum = 0;for (int i = 0; i < 500000000L; i++) {sum += i;}System.out.println(sum);Instant end = Instant.now();//单线程 602毫秒System.out.println("5亿数据求和花费的时间->" + Duration.between(start, end).toMillis() + "毫秒");}//    并行流底层实现原理@Testpublic void streamParallel() {Instant start = Instant.now();LongStream longStream = LongStream.rangeClosed(0, 500000000L);OptionalLong result = longStream.parallel().reduce((left, right) -> left + right);System.out.println(result.getAsLong());Instant end = Instant.now();//多线程 613毫秒System.out.println("5亿数据求和花费的时间->" + Duration.between(start, end).toMillis() + "毫秒");}
}

方法引入

package com.gblfy.lambda;import com.gblfy.elk.entity.User;
import com.gblfy.elk.lambda.drawinto.*;
import org.junit.Test;public class MethodInto {//静态方法引入@Testpublic void staticMethodInto() {// 1.使用匿名内部类的形式 调用get方法// new MessageInterface() {//     @Override//     public void get(Integer i) {//         MethodReference.getStaticMethod(i);//     }// }.get(1);//2.lambda 形式// MessageInterface messageInterface = (i) -> {//     MethodReference.getStaticMethod(i);// };// messageInterface.get(2);//处理逻辑只有一行大括号可以省略// MessageInterface messageInterface = (i) -> MethodReference.getStaticMethod(i);// messageInterface.get(2);//3.使用方法引入,必须满足方法引入的方法必须和函数中的方法参数列表和返回值保持一致// MessageInterface messageInterface = MethodReference::getStaticMethod;// messageInterface.get(2);/*** 分析* (i) -> MethodReference.getStaticMethod(i) 等于 MethodReference::getStaticMethod* lambda 使用方法引入,要求:必须满足方法引入的方法必须和函数中的方法参数列表和返回值保持一致*///精简写法((MessageInterface) MethodReference::getStaticMethod).get(2);}//实例方法引入@Testpublic void exampleMethodInto() {// MethodInto methodInto = new MethodInto();// MessageInterface2 messageInterface2 = () -> methodInto.objGet();// System.out.println(messageInterface2.getMessage());MethodInto methodInto = new MethodInto();MessageInterface2 messageInterface2 = methodInto::objGet;System.out.println(messageInterface2.getMessage());}//实例对昂方法public String objGet() {return "1111111";}//构造函数引入@Testpublic void functionMethodInto() {// UserInterface userInterface = () -> {//     return new User();// };UserInterface userInterface = User::new;System.out.println(userInterface.getUser());}}

对象方法引入

@FunctionalInterface
public interface LyService {String get(ObjMethodInto objMethodInto);
}pac
kage com.gblfy.elk.lambda.drawinto;import java.util.function.Function;public class ObjMethodInto {//对象方法引入public static void main(String[] args) {//1.使用匿名内部类形式// LyService lyService = new LyService() {//     @Override//     public String get(ObjMethodInto objMethodInto) {//         return objMethodInto.objGet();//     }// };// System.out.println(lyService.get(new ObjMethodInto()));//2.lambda// LyService lyService = (objMethodInto) -> objMethodInto.objGet();// System.out.println(lyService.get(new ObjMethodInto()));//3.对象方法引入// LyService lyService = ObjMethodInto::objGet;// System.out.println(lyService.get(new ObjMethodInto()));/*** 分析* ObjMethodInto::objGet 等同于 (objMethodInto) -> objMethodInto.objGet()*///    案例//    需要将string类型的字符串获取长度// Function<String, Integer> stringIntegerFunction = (str)->str.length();// System.out.println(stringIntegerFunction.apply("gblfy"));Function<String, Integer> stringIntegerFunction = String::length;System.out.println(stringIntegerFunction.apply("gblfy"));}//实例对昂方法public String objGet() {return "1111111";}
}

OptionalCase

package com.gblfy.lambda;import org.junit.Test;import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;public class OptionalCase {public static final String USER_NAME = "gb";//判断参数是否为空//说明:空字符串不为null@Testpublic void isNull() {/*** ofNullable(可以传递一个空对象)* Of(不可以传递空对象)*/String username = "gbl";// String username = "";// String username = null;Optional<String> optional = Optional.ofNullable(username);// Optional<String> optional = Optional.of(username);boolean present = optional.isPresent();if (present) {System.out.println("username不为空");}}//参数为空可以设定默认值@Testpublic void isNullSetDefault() {// String username = null;String username = "gbl";String optional = Optional.ofNullable(username).orElse("123456");System.out.println(optional);}//参数实现过滤@Testpublic void paramFilter() {String username = null;boolean present = Optional.ofNullable(username).filter(p -> USER_NAME.equals(p)).isPresent();System.out.println(present);}//与Lambda表达式结合使用,优化代码@Testpublic void ifPresent() {String username = null;//优化前if (username != null) {System.out.println(username);}//优化后//lambda 简写形式// Optional.ofNullable(username).ifPresent(s -> System.out.println(s));//方法引入 简写形式Optional.ofNullable(username).ifPresent(System.out::print);}//    优化方案2@Testpublic void ifPresent2() {}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/515902.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文聊“图”,从图数据库到知识图谱

作者 | 穆琼责编 | 晋兆雨头图 | 付费下载于视觉中国随着知识图谱的发展&#xff0c;图数据库一词被越来越多的提到。那么到底什么是图数据库&#xff0c;为什么要用图数据库&#xff0c;如何去建设一个图数据库应用系统&#xff0c;图数据库与知识图谱到底是什么关系。今天为大…

阿里云机器学习PAI DSW 2.0 Alink商业版重磅发布

DSW 2.0&#xff1a;面向AI研发的集成开发平台 DSW&#xff08;Data Science Workshop&#xff09;是阿里巴巴PAI团队根据多年的AI算法和产品研发经验积累&#xff0c;围绕提高AI算法研发效率&#xff0c;降低研发成本而推出的一款适用于各类AI开发者的云端机器学习集成开发环…

DSW:面向AI研发的集成开发平台

发布会传送门 产品详情 云原生技术&#xff0c;注重用户体验&#xff0c;提升研发效率 环境搭建是算法研发过程中的重要一环&#xff0c;这里除了硬件选型外&#xff0c;软件环境的安装配置&#xff0c;后续升级往往会耗费不少时间。DSW借助阿里云ECS&#xff0c;Docker和Ku…

程序员应如何理解高并发中的协程

来源 | 码农的荒岛求生责编 | 晋兆雨头图 | 付费下载于视觉中国作为程序员&#xff0c;想必你多多少少听过协程这个词&#xff0c;这项技术近年来越来越多的出现在程序员的视野当中&#xff0c;尤其高性能高并发领域。当你的同学、同事提到协程时如果你的大脑一片空白&#xff…

5G边缘计算行业通识:阿里云ENS技术演进之路

近日&#xff0c;阿里云杨敬宇在CSDN阿里云核心技术竞争力在线峰会上进行了《5G基础设施-阿里云边缘计算的技术演进之路》主题演讲&#xff0c;针对5G时代下&#xff0c;行业和技术的趋势、边缘计算产业通识以及阿里云边缘计算从过去到未来的技术演进之路进行分享。 5GAI需求推…

精讲23种设计模式-策略模式~聚合短信服务和聚合支付服务

文章目录一、设计模式1. 为什么需要使用设计模式2. 设计模式的分类3. 什么是策略模式4. 为什么叫做策略模式5. 策略模式优缺点6. 策略模式应用场景7. Spring框架中使用的策略模式二、策略模式~聚合短信服务2.1. 依赖引入2.2. 抽象公共行为接口2.3. 具体策略接口实现类2.4. 策略…

引领开源新风潮,阿里巴巴编程之夏第二期重磅来袭!

“唯有热爱&#xff0c;可抵岁月漫长”。 2020 年 5 月 25 日&#xff0c;阿里巴巴编程之夏&#xff08;Alibaba Summer of Code&#xff0c;以下简称 ASoC &#xff09;第二期正式上线&#xff0c;项目规模再度升级&#xff0c;来自开源社区的 Apache Dubbo、Apache RocketMQ…

powerdesigner逆向工程(sql转pdm)

第一步&#xff1a; File -> Reverse Engineer -> Database 第二步 &#xff1a; Using Script Files -> Add Files

安谋中国发布“玲珑”i3i5 ISP处理器,剑指何方?

随着图像视频处理技术的发展和 5G 时代的来临&#xff0c;除了社交等平台外&#xff0c;以图像、视频为载体的内容渗透到各领域&#xff0c;特别是智能安防、AIoT、智能汽车等新兴领域应用。与此同时&#xff0c;人们对其清晰度、图像分辨率有新的扩展需求&#xff0c;对摄像头…

凯度信息之美奖揭晓,数据可视化后有多“性感”?

前言&#xff1a;更多关于数智化转型、数据中台内容可扫码加群一起探讨 阿里云数据中台官网 https://dp.alibaba.com/index &#xff08;作者&#xff1a;常成&#xff09; 2019年的“凯度信息之美奖”揭晓了&#xff0c;有很多很有意思的信息可视化作品。很多作品看到的时候…

精讲23种设计模式-基于责任链模式~构建企业级风控系统

文章目录一、责任链1. 责任链基本概念2. 定义3. 关键要点4. 责任链模式优缺点5. 责任链模式类结构图6. 网关权限控制责任链模式二、构建企业级风控系统2.1. 定义公共抽象任务2.2. (失信名单)校验处理类2.3. (信用卡)逾期处理类2.4. (蚂蚁信用积分)处理类2.5. 责任链工厂(第一种…

抓取了《大秦赋》所有数据,我发现了这些秘密

本文由黄勇老师特约供稿学习人数超13万人的<Python入门到实战一卡通>作者网易、360、华为特约Python讲师前言最近大火的电视剧《大秦赋》&#xff0c;给朋友圈的小伙伴都拉回到那个风云激荡的春秋战国时期&#xff0c;大家都在热情的讨论着大秦一统&#xff0c;秦始皇嬴政…

精讲23种设计模式-基于观察者模式~设计异步多渠道群发框架

文章目录一、观察者模式1. 观察者模式基本概念2. 观察者模式的应用场景3. 观察者模式的类图二、设计异步多渠道群发框架2.1. 定义消息观察者抽象接口2.2. 创建观察者2.3. 主题通知所有观察者2.4. 观察者注册2.5. 自定义线程池2.6. 签单通知入口2.6. 异步通知接口测试2.7. 依赖三…

君子动手不动口,阿里云喊你做云上体验官啦!

想要免费搭建云上博客&#xff1f;想要玩转全云端开发&#xff1f;想要挑战AI经典命题&#xff1f;想要7天进阶成为云计算专家&#xff1f;想要初始化你的云原生工程&#xff1f;快来阿里云 Hands-on Labs&#xff01; Hands-on Labs 是阿里云全新推出的云上动手实验室&#x…

我是Redis,MySQL大哥被我害惨了!

来源 | 编程技术宇宙责编 | 晋兆雨头图 | 付费下载于视觉中国我是Redis你好&#xff0c;我是Redis&#xff0c;一个叫Antirez的男人把我带到了这个世界上。说起我的诞生&#xff0c;跟关系数据库MySQL还挺有渊源的。在我还没来到这个世界上的时候&#xff0c;MySQL过的很辛苦&a…

联手友盟+打造云上数据增长“样板间”, 好兔视频成功逆势突围

前言&#xff1a;更多关于数智化转型、数据中台内容可扫码加群一起探讨 阿里云数据中台官网 https://dp.alibaba.com/index &#xff08;作者&#xff1a;友盟&#xff09; “消费升级”是近年来的中国消费市场热门词汇&#xff0c;消费升级的同时也驱动了内容消费升级。在这样…

SpringBoot 使用 Caffeine 本地缓存

文章目录一、本地缓存介绍二、缓存组件 Caffeine 介绍2.1. Caffeine 性能2.2. Caffeine 配置说明2.3. 软引用与弱引用三、SpringBoot 集成 Caffeine 方式一3.1. Maven 引入相关依赖3.2. 配置缓存配置类3.3. 定义实体对象3.4. 定义服务接口类3.5. 定义服务接口实现类3.6. Caffei…

《Istio 从懵圈到熟练:二分之一活的微服务》

作者 | 声东 阿里云售后技术专家 <关注阿里巴巴云原生公众号&#xff0c;回复 排查 即可下载电子书> 《深入浅出 Kubernetes》一书共汇集 12 篇技术文章&#xff0c;帮助你一次搞懂 6 个核心原理&#xff0c;吃透基础理论&#xff0c;一次学会 6 个典型问题的华丽操作…

为了追求更快,CPU、内存、I/O都做了哪些努力?

来源 | 编程技术宇宙责编 | 晋兆雨头图 | 付费下载于视觉中国背景曾经&#xff0c;我面试的时候有两个最怕的。一怕问算法&#xff0c;二怕问高并发。算法这个&#xff0c;自从刷了不少LeetCode&#xff0c;发现还是有套路可循的&#xff0c;虽不敢说算法能力有多强&#xff0c…