Java 8 中的方法引用

一、原理概要

lambda 表示式,可以作为某些匿名内部类的替代。主要目的是调用该内部类中的方法,而该方法的实现(重写)由 lambda表示式决定。

通常,我们可能不关心匿名内部类中的具体方法(被重写的方法),而只关心该方法是怎么被重写的(方法的实现)。因此,我们可以构造一个中间对象(通常是接口,比如 Funtion),该接口拥有一个需要该重写的方法(比如 Function 对应的方法是 apply)。

二、如何使用

在实际书写时,可以只写出(传递的参数)与{方法的实现},或者只标出实现过程的 调用者的和其方法名(使用冒号分隔)。

Function<Person, Integer> getAge = Person::getAge;
// 传参数调用 getAge 方法
Integer age = getAge.apply(p);

注释:

1. 比如 Function<T,R>T 表示传入类型,R 表示返回类型。比如,表达式 person -> person.getAge();,传入参数是 person,返回值是 person.getAge(),那么方法引用 Person::getAge 就对应着 Function<Person,Integer> 类型。

2. 使用双冒号的方式会返回这个对象,当你调用该对象中的 apply 方法时,就会调用你之前传进去的方法。

3. 这个过程类似一个函数的闭包。当你使用双冒号的方式,会把你的类和方法传入并生成一个 Function对象。该对象会在之后某个时间被调用,此时它会调用之前你传入这个对象中的方法。

4. 三种方式对比

// old way
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
for (Integer n : list) {
    System.out.println(n);
}

// 使用 -> 的 Lambda 表达式
list.forEach(n -> System.out.println(n));

// 使用 :: 的 Lambda 表达式
list.forEach(System.out::println);

  

三、关于函数式接口

1. Java 8中允许接口实现方法, 而不是简单的声明。需要使用关键字 default

2. Java8 中的 函数式接口中除了定义抽象方法外还可以包含静态方法。

@FunctionalInterface
interface FunctionalInterfaceWithStaticMethod {
	static int sum(int[] array) {
		return Arrays.stream(array).reduce((a, b) -> a+b).getAsInt();
	}

	void apply();
}

注. @FunctionalInterface注解,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。 

 

3.一般情况下函数式接口只会定义一个抽象方法,但是接口最终有确定的类实现, 而类的最终父类是Object。 因此函数式接口可以定义Object 中的public方法,protected 方法不行。

@FunctionalInterface
public interface ObjectMethodFunctionalInterface {
	void count(int i);

	String toString(); //same to Object.toString
	int hashCode(); //same to Object.hashCode
	boolean equals(Object obj); //same to Object.equals
}

  

4. util 包中的函数式接口

java.util.function中定义了几组类型的函数式接口以及针对基本数据类型的子接口。

  • Predicate -- 传入一个参数,返回一个bool结果, 方法为boolean test(T t)
  • Consumer -- 传入一个参数,无返回值,纯消费。 方法为void accept(T t)
  • Function<t,r> -- 传入一个参数,返回一个结果,方法为R apply(T t)
  • Supplier -- 无参数传入,返回一个结果,方法为T get()
  • UnaryOperator -- 一元操作符, 继承Function<t,t>,传入参数的类型和返回类型相同。
  • BinaryOperator -- 二元操作符, 传入的两个参数的类型和返回类型相同, 继承BiFunction

原文地址:https://www.cnblogs.com/lemos/p/9244651.html

时间: 2024-11-11 13:00:02

Java 8 中的方法引用的相关文章

浅谈Java 8中的方法引用(Method References)

本人接触Java 8的时间不长,对Java 8的一些新特性略有所知.Java 8引入了一些新的编程概念,比如经常用到的 lambda表达式.Stream.Optional以及Function等,让人耳目一新.这些功能其实上手并不是很难,根据别人的代码抄过来改一下,并不要知道内部的实现原理,也可以很熟练地用好这些功能.但是当我深究其中一些细节时,会发现有一些知识的盲区.下面我就来谈一下Java 8中的Method References这个概念. 首先我给出官方对于这一概念的详细解释,https:/

Swift编程语言中的方法引用(基于2.2版本)

由于Apple官方的<The Swift Programming Guide>对Swift编程语言中的方法引用介绍得不多,所以这里将更深入.详细地介绍Swift中的方法引用. Swift与Objective-C不同,由于Objective-C的方法都属于“消息”,因此直接用selector的消息签名即可表示一条确定的消息作为方法引用.而Swift的方法更类似于C++.Java中的方法,也就是说比Objective-C更静态,因此它不具有如此般灵活性. 另外,在Swift编程语言中,方法引用与C

jsp中怎么调用java类中的方法

在jsp页面中先要,引入java类 例如: <%@page import="javabean.DbConn"%><!-- 引入包中的"类" --> <!--在用到的地方,直接对类实例化--> <% DbConn  DB=new  DbConn(); %> <!--然后就可以直接调用类中的方法--> <% Connection con=DB.conn(); %> jsp中怎么调用java类中的方法

java8中的方法引用与构造器引用

java8中的方法引用与构造器引用 方法引用:若Lambda体中的内容有方法已经实现了,我们可以使用"方法引用" 主要的三种语法格式: 对象::实例名 类::静态方法名 类::实例方法名 注意: Lmabda体中调用方法的参数列表与返回值类型要与函数式接口中抽象方法的函数列表和返回值类型保持一致 若Lambda参数列表中的第一参数是 实例方法的调用者,而第二个参数是 实例方法的参数时,可以使用ClassName::method public class Employee { priva

java中的方法引用

引用静态方法:类名称::static 方法名称: 引用某个对象的方法:对象::普通方法: 引用特定类方法:特定类::方法 引用构造方法:类名称::new 范例:引用静态方法 package com.java.demo; interface IMessage<P,R>{ // P表示方法的参数类型,R表示方法的返回值类型 public R change(P p); } public class TestDemo{ public static void main(String args[]){ /

java基础-四种方法引用

实例 直接三角形,通过两边算第三边,目的是为了如何使用这几种方法引用.代码中多有些不合适,尽情原谅. 静态方法引用 接口的参数列表与类中的具体实现方法的参数列表一样,返回值一致. 调用 //静态引用 IStaticSide staticSide = Five::getStaticSize; staticSide.getStaticSize(3, 6); 类中定义 //静态引用 public static double getStaticSize(double s,double s2) { ret

java String 中 intern方法的概念

1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. new String()和new String(“”)都是申明一个新的空字符串,是空串不是null: 3. String str=”kvill”:String str=new String (“kvill”);的区别: 在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念. 常量池(const

第6章 Java类中的方法

1.如何定义java的方法 什么是方法:方法使用来解决一类问题的代码集合,是一个功能模块在类中定义个方法的方法是: 访问修饰符 返回值类型 方法名(参数列表){ 方法体 } 1.访问修饰符,是限制该方法允许被访问的权限范围,可以是:public,protected,private还可以省略2.返回值,如果有返回值需要在这里说明类型,并用return返回,如果没有返回值,使用void3.方法名,使用标识符命名4.参数列表,传递给方法的参数列表 根据返回值和参数的不同,方法大致上分为一下四类:? 无

java#lambda相关之方法引用

lambda在java中通常是()->{}这样的方式,来书写的.通常的lambda是四大函数型接口的一个“实现”. 如果我们要写的lambda已经有现成的实现了,那么就可以把现成的实现拿过来使用,这就是方法引用.所以被引用的方法的参数和返回值应该和lambda的参数和返回值是一致的. List<String> strings = Arrays.asList("123", "456", "789"); // 1 strings.f