Java8特性

mac2026-01-12  8

1.lambda表达式:

加入lambda之后,很多写法都变得简单起来,如创建一个线程对象

new Thread(new Runnable() { @Override public void run() { System.out.print("Hello"); } }); lambda写法: new Thread(() -> System.out.print("Hello")); 单独将lambda拎出来: Runnable runnable = () -> System.out.print("Hello"); 其实lambda代表的就是一个接口的实现而已(匿名内部类)。 而这种接口也叫函数式接口,会有@FunctionalInterface注解进行编译时检查。 或者直接把lambda看成一个方法,上述的 () -> System.out.print("Hello") 就是代表一个无入参、无返回值的一个方法(等同于public void run() {System.out.print("Hello")}),而Runnable runnable则是指向这个方法(类似函数指针),需要调用这个方法时,调用runnable.run()即可. 当有一个参数、无返回值则是Consumer<T> // 对printStream对象的void print(String s)方法的引用 PrintStream printStream = System.out; Consumer<String> consumer = printStream::print; consumer.accept("Hello"); // 输出 Hello

以上为java.util.function包下的部分接口,剩余的基本上就是指定泛型类型的函数接口了,例如LongConsumer,无泛型,其实就是指定入参只能是Long。 上述已经代表了大部分的函数可以表示的形式了(值得注意的是,三个及以上的入参的函数式接口JDK并没有提供,需要时要自定义实现,实际上也很少用到)。 方法有静态方法(static)和非静态方法,但函数式接口关注的仅是入参、出参类型和个数而已: public Class Test { public Long noStaticFoo(String str) {...} public static Long staticFoo(String str) {...} public static void main() { // 静态方法,类:: Function<String, Long> staticFoo = Test::staticFoo; Long apply = staticFoo.apply("100"); // 非静态方法,实例对象:: Test test = new Test(); Function<String, Long> noStaticFoo = test::noStaticFoo; Long apply2 = noStaticFoo.apply("100"); /* 这种可以理解成两个入参、除了原来方法的入参外,还要指明实例对象(因为这是一个实例方法)*/ BiFunction<Test, String, Long> noStaticFooTest = Test::noStaticFoo; Long apply3 = noStaticFooTest.apply(test, "100"); } }

java8异步方法调用写法

public class UserHttpService { public User getById(Long id) { ... return user; } } public class AsyncExecutor { // 线程池,建议恰当配置(拒绝策略建议CallerRunsPolicy)和使用框架注入 private ExecutorService executorService = Executors.newFixedThreadPool(10); /** * 单个入参,有返回值的异步执行方法 , public User getById(Long id) * * @param method 要执行的方法,如 , userHttpService::getById * @param param 入参值,如 100 * @param <P> 入参类型,如 Long * @param <R> 返回值类型,如 User * @return Future对象,用以判断是否执行结束、获取返回结果 */ public <P, R> Future<R> async(Function<P, R> method, P param) { return executorService.submit(() -> method.apply(param)); } } public class A { private AsyncExecutor asyncExecutor; private UserHttpService userHttpService; public void foo() { ... // 异步调用 Future<User> userFuture = asyncExecutor.async(userHttpService::getById, id); ... 其他操作(如再发起http请求) // 获取结果 User user = userFuture.get(); ... } } public class AsyncExecutor { // 线程池,建议恰当配置(拒绝策略建议CallerRunsPolicy)和使用框架注入 private ExecutorService executorService = Executors.newFixedThreadPool(10); /** * 无入参,无返回值的异步执行方法 , void noStaticFoo() * * @param method 要执行的方法,如 user::noStaticFoo; * @return Future对象,用以判断是否执行结束 */ public Future async(Runnable method) { return executorService.submit(method); } /** * 有单个入参,无返回值的异步执行方法,如 void noStaticFoo(Long id) * * @param method 要执行的方法,如, user::noStaticFoo * @param param 方法执行的入参,如id * @param <P> 入参类型,如Long * @return Future对象,用以判断是否执行结束 */ public <P> Future async(Consumer<P> method, P param) { return executorService.submit(() -> method.accept(param)); } /** * 有两个参数但是无返回值的异步执行方法, 如void noStaticFoo(Long id,Entity entity) * * @param method 要执行的方法,如 , user::noStaticFoo * @param param1 第一个入参值,如id * @param param2 二个入参值,如entity * @param <P1> 第一个入参类型 * @param <P2> 第二个入参类型 * @return Future对象,用以判断是否执行结束 */ public <P1, P2> Future async(BiConsumer<P1, P2> method, P1 param1, P2 param2) { return executorService.submit(() -> method.accept(param1, param2)); } /** * 无参数有返回值的异步执行方法 , Entity noStaticFoo() * * @param method 要执行的方法,如 , user::noStaticFoo * @param <R> 返回值类型,如 Entity * @return Future对象,用以判断是否执行结束、获取返回结果 */ public <R> Future<R> async(Supplier<R> method) { return executorService.submit(method::get); } /** * 单个入参,有返回值的异步执行方法 , Entity noStaticFoo(Long id) * * @param method 要执行的方法,如 , user::noStaticFoo * @param param 入参值,如 id * @param <P> 入参类型,如Long * @param <R> 返回值类型,如 Entity * @return Future对象,用以判断是否执行结束、获取返回结果 */ public <P, R> Future<R> async(Function<P, R> method, P param) { return executorService.submit(() -> method.apply(param)); } /** * 两个入参,有返回值的异步执行方法 , Entity noStaticFoo(Long id) * * @param method 要执行的方法,如 , user::noStaticFoo * @param param1 第一个入参值,如id * @param param2 二个入参值,如entity * @param <P1> 第一个入参类型 * @param <P2> 第二个入参类型 * @param <R> 返回值类型,如 Entity * @return Future对象,用以判断是否执行结束、获取返回结果 */ public <P1, P2, R> Future<R> async(BiFunction<P1, P2, R> method, P1 param1, P2 param2) { return executorService.submit(() -> method.apply(param1, param2)); } } JDK1.8 有提供CompletableFuture,也是类似异步处理的方法,默认线程池为ForkJoinPool(默认最大工作线程数=CPU总核心数-1),该线程池擅长于计算密集型任务,IO密集型任务请尽量使用自己合理配置的线程池。

函数式接口

函数式接口就是只定义一个抽象方法的接口.例如:Comparator和Runnable 和 Predicate 和 FileFilter 接口现在还可以拥有默认方法(即在类没有对方法进行实现时, 其主体为方法提供默认实现的方法)。 哪怕有很多默认方法,只要接口只定义了一个抽象 方法,它就仍然是一个函数式接口。 注意(函数式接口): 函数式接口中可以额外定义多个抽象方法,但这些抽象方法签名必须和Object的public方法一样 接口最终有确定的类实现, 而类的最终父类是Object。Comparator有两个抽象方法(compare和equals方法) ,Comparator类的equals方法名和Object的equals方法一样. 所有类默认继承Object,所以该类已有了Object的equals方法,相当于重写了equals方法。

用函数式接口可以干什么呢? Lambda表达式允许你直接以内联的形式为函数式接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例(具体说来,是函数式接口一个具体实现 的实例)。 你用匿名内部类也可以完成同样的事情,只不过比较笨拙:需要提供一个实现,然后 再直接内联将它实例化。 下面的代码是有效的,因为Runnable是一个只定义了一个抽象方法run 的函数式接口:

函数描述符: 函数式接口的抽象方法的签名基本上就是Lambda表达式的签名。我们将这种抽象方法叫作 函数描述符。 例如,Runnable接口可以看作一个什么也不接受什么也不返回(void)的函数的 签名,因为它只有一个叫作run的抽象方法, 这个方法什么也不接受,什么也不返回(void)。 Java重用了函数式接口提 供的标准类型,并将其映射成一种形式的函数类型。

Java 8的库设计师帮你在java.util.function包中引入了几个新的函数式接:Predicate、Consumer 、Function https://blog.csdn.net/a879611951/article/details/80104014 四大核心函数接口 Function<T, R> T:入参类型,R:出参类型 调用方法:R apply(T t); 定义函数示例:Function<Integer, Integer> func = p -> p * 10; // 输出入参的10倍 调用函数示例:func.apply(10); // 结果100 例如: Function<Integer, Integer> fun1 = n->n*2 ; fun1.apply(3); public static void main(String[] args) { List<Integer> weights = Arrays.asList(7, 3, 4, 10); Function<Integer, Apple> intConsumer = Apple::new; List<Apple> apples = map(weights,Apple::new); System.out.println(JSON.toJSONString(apples)); } public static List<Apple> map(List<Integer> list, Function<Integer, Apple> f) { List<Apple> result = new ArrayList<>(); for (Integer e : list) { Apple apply = f.apply(e); result.add(f.apply(e)); } return result; } 运行结果:[{"weight":7},{"weight":3},{"weight":4},{"weight":10}] Supplier<T> T:出参类型;没有入参 调用方法:T get(); 定义函数示例:Supplier<Integer> supplier= () -> 100; // 常用于业务“有条件运行”时,符合条件再调用获取结果的应用场景;运行结果须提前定义,但不运行。 调用函数示例:supplier.get(); 例如: Supplier<String> supplier = String::new; System.out.println(supplier.get());//"" Supplier<Emp> supplierEmp = Emp::new; Emp emp = supplierEmp.get(); emp.setName("dd"); System.out.println(emp.getName());//dd Consumer<T> T:入参类型;没有出参 调用方法:void accept(T t); 定义函数示例:Consumer<String> consumer= p -> System.out.println(p); // 因为没有出参,常用于打印、发送短信等消费动作 调用函数示例:consumer.accept("18800008888"); Predicate<T> 用于判断, 定义的函数只会返回true或false 例如: Predicate<String> isEmpty = String::isEmpty; Predicate<String> isEmpty1 = (String str) ->str.isEmpty(); T:入参类型;出参类型是Boolean 调用方法:boolean test(T t); 定义函数示例:Predicate<Integer> predicate = p -> p % 2 == 0; // 判断是否、是不是偶数 调用函数示例:predicate.test(100); // 运行结果true Consumer<String> aa= a-> System.out.println(a); Consumer<String> aa1= System.out::println; getLowCaloricDishesNamesInJava8(Dish.menu).forEach(aa); public static List<String> getLowCaloricDishesNamesInJava8(List<Dish> dishes){ //Dish类 calories变量 getCalories 是calories变量的get方法 Comparator<Dish> comparing = comparing(Dish::getCalories); Function<Dish, String> getName = Dish::getName; List<String> collect = dishes.stream() .filter(d -> d.getCalories() < 400) .sorted(comparing(Dish::getCalories)) .map(Dish::getName) .collect(toList()); return collect; } https://www.cnblogs.com/lijingran/p/8708037.html java编程Consumer和Predicate案例 //修改属性的值 @Test public void test(){ UserT userT = new UserT("zm"); //接受一个参数 Consumer<UserT> userTConsumer = userT1 -> userT1.setName("zmChange");}; userTConsumer.accept(userT); logger.info(userT.getName());//输出zmChange } public class PredicateConsumerDemo { public static Student updateStudentFee(Student student, Predicate<Student> predicate, Consumer<Student> ){ if (predicate.test(student)){ consumer.accept(student); } return student; } } public class Test { public static void main(String[] args) { Student student1 = new Student("Ashok","Kumar", 9.5); student1 = updateStudentFee(student1, student -> student.grade > 8.5, student -> student.feeDiscount = 30.0); student1.printFee(); Student student2 = new Student("Rajat","Verma", 8.0); student2 = updateStudentFee(student2, student -> student.grade >= 8, student -> student.feeDiscount = 20.0); student2.printFee(); } }

最新回复(0)