Java8引入了Lambda表达式,可以不必编写FunctionalInterface的实现类,直接写Lambda表达式。除了Lambda表达式,我们还可以直接传入方法引用

方法引用是指:如果某个方法签名和接口恰好一致,可以直接传入方法引用,格式:类名::方法名

静态方法引用

在SortedBy这个类中定义了一个静态方法,其方法签名是传入2个String,返回int。

class SortedBy{
static int nameIgnoreCase(String s1, String s2){
return s1.toLowerCase.compareTo(s2.toLowerCase());
}
}

此时和范型的Comparator接口比较,这2个方法签名是一致的。

注意:这里的方法签名只看方法类型和返回值类型。

```#java
interface Comparator{
int compare(String s1, String s2);
}
```
ignoreCase恰好符合Comparator的接口定义。因此在需要传入Comparator的地方,我们直接传入方法引用
```#java
public static void main(String[] args){
String[] array = "Java Apple lambda functional OOP".split(" ");
Arrays.sort(array,SortedBy::nameIgnoreCase);
System.out.println(Arrays.toString(array));
}
```

实例方法引用

public class String{
public int compareToIgnoreCase(String s){
...
}
}

String的compareToIgnoreCase参数是String,返回值是int,看上去并不符合Comparator接口的定义。

但是实例方法调用时,必须有一个隐含的实例变量。即调用String类的compareToIgnoreCase必须有一个String类型的实例,实例参数+方法参数就通Comparator接口定义是一致的。

注意:隐含的this实例变量是方法的第一个参数。

Arrays.sort(array, String::compareToIgnoreCase);
//=>instance.compareToIgnoreCase(s)
//=> Comparator.compare(instance, s)

构造方法引用

class Person{
String name;
public Person(String name){
this.name = name;
}
}

把一个String类型的List转化为Person类型的List?

方法1:先定义一个ArrayList,然后用for循环来填充这个List。

    List<String> names = Arrays.asList("Bob", "Alice", "Tim");
List<Person> person = new ArrayList<>();
for(String name: names){
Person p = new Person(name);
persons.add(p);
}

方法2:直接引用Person类的构造方法,不用手动创建Person实例

map()传入的方法签名:参数为String,返回值为Person对象。编译器自动查找符合条件的构造方法

构造方法的引用为:类名::new

虽然Java构造方法内部不能持有return语句,但构造方法是有返回值的,它的返回值是this,即当前实例。

    List<String> names = Arrays.asList("Bob", "Alice", "Tim");
List<Person> persons = names.stream().map(Person::new).collect(collectors.toList());
import java.util.Arrays;

class SortedBy {
static int name(String s1, String s2) {
return s1.compareTo(s2);
} static int nameIgnoreCase(String s1, String s2) {
return s1.toLowerCase().compareTo(s2.toLowerCase());
} static int length(String s1, String s2){
int n1 = s1.length();
int n2 = s2.length();
if(n1==n2){
return s1.compareTo(s2);
}
return n1 < n2 ? -1:1;
}
}
public class LambdaSort {
public static void main(String[] args){
String[] array = "Java Apple lambda functional OOP".split(" ");
Arrays.sort(array,SortedBy::nameIgnoreCase);
System.out.println(Arrays.toString(array));
}
}

总结

Functional Interface可以传入:

  • 接口的实现类(代码较繁琐)
  • Lambda表达式
  • 符合方法签名的静态方法
  • 符合方法签名的实例方法(实例类型被看作第一个参数类型)
  • 符合方法签名的构造方法(实例类型被看作返回类型)

廖雪峰Java16函数式编程-1Lambda表达式-3方法引用的更多相关文章

  1. 廖雪峰Java16函数式编程-1Lambda表达式-1Lambda基础

    1. 函数式编程 Java有2类方法: 实例方法:通过实例调用 静态方法:通过类名调用 Java的方法相当于过程式语言的函数 函数式编程(Functional Programing): 把函数作为基本 ...

  2. 廖雪峰Java16函数式编程-2Stream-7其他操作

    1. 排序 Stream<T> sorted(); //按元素默认大小排序(必须实现Comparable接口) Stream<T> sorted(Comparator<? ...

  3. 廖雪峰Java16函数式编程-2Stream-6reduce

    1. 聚合方法 Stream.reduce()是一个Stream的聚合方法:把一个Stream的所有元素聚合成一个结果 例如: Stream.of(1, 2, 3, 4, 5).count(); // ...

  4. 廖雪峰Java16函数式编程-2Stream-5filter

    1.filter简介 Stream.filter()是一个转换方法,把一个Stream转换为另一个Stream. 所谓filter操作,就是对一个Stream的所有元素进行测试,不满足条件的元素就被过 ...

  5. 廖雪峰Java16函数式编程-2Stream-4map

    1. map()简介 Stream.map()是一个Stream的转换方法,把一个stream转换为另一个Stream,这2个Stream是按照映射函数一一对应的. 所谓map操作,就是把一种操作运算 ...

  6. 廖雪峰Java16函数式编程-2Stream-2创建Stream

    1. 方法1:把一个现有的序列变为Stream,它的元素是固定的 //1.直接通过Stream.of()静态方法传入可变参数进行创建 Stream<Integer> s = Stream. ...

  7. 廖雪峰Java16函数式编程-2Stream-1Stream简介

    1. Stream Java8引入全新的Stream API 位于java.util.stream包 1.1 Stream API不同于java.io的InputStream/OutputStream ...

  8. [python学习篇][廖雪峰][2]函数式编程

    函数名也是变量: >>> f = abs >>> f(-10) 10 然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就 ...

  9. Java中的函数式编程(四)方法引用method reference

    写在前面 我们已经知道,lambda表达式是一个匿名函数,可以用lambda表达式来实现一个函数式接口.   很自然的,我们会想到类的方法也是函数,本质上和lambda表达式是一样的,那是否也可以用类 ...

随机推荐

  1. 待办消息查询sql

    select tsm.TMsgID,tsm.TMID,tsm.FNRID,tm.MainComID, tsm.TMsgName,fb.FBDataTbale, tsm.REMARK,fb.FlowTy ...

  2. 精选 Dubbo RPC 面试题,比较全面,含答案

    精选 Dubbo RPC 面试题,比较全面,含答案 hu1991die 搜云库技术团队 搜云库技术团队 微信号 souyunku 功能介绍 专注于分享最有价值的互联网技术干货文章,内容覆盖,Java后 ...

  3. UNLISTEN - 停止监听通知信息

    SYNOPSIS UNLISTEN { name | * } DESCRIPTION 描述 UNLISTEN 用于删除一个现有的已注册的 NOTIFY 事件. UNLISTEN 取消当前 Postgr ...

  4. CAS -- ABA问题的解决方案

    我们现在来说什么是ABA问题.假设内存中有一个值为A的变量,存储在地址V中. 此时有三个线程想使用CAS的方式更新这个变量的值,每个线程的执行时间有略微偏差.线程1和线程2已经获取当前值,线程3还未获 ...

  5. CF755G PolandBall and Many Other Balls/soj 57送饮料

    题意:长度为n的序列,相邻两个或单独一个可以划分到一个组,每个元素最多处于一个组. 问恰好分割成k(1<=k<=m)段有多少种方案? 标程: #include<bits/stdc++ ...

  6. windows10 自动配置切换IP

    办公室与家里的ip网段不一样.每次都要来回修改本地无线WLAN IP段.写了个脚本bat,自动配置WLAN IP,方便切换. 建立 auto-set-ip.bat,保存格式需为ANSI,否则中文会乱码 ...

  7. JUC 一 ReentrantLock 可重入锁

    java.util.concurrent.locks ReentrantLock即可重入锁,实现了Lock和Serializable接口 ReentrantLock和synchronized都是可重入 ...

  8. NX二次开发-获取UG界面窗口句柄UF_UI_get_default_parent

    1 extern "C" DllExport void ufusr(char *param, int *retcod, int param_len) 2 { 3 4 if (UF_ ...

  9. phpstorm激活 破解 方法

    1.license server 在线激活方式 不是很推荐,自己有服务器的话可以考虑搭建 所以就不说了. 不过我在网上找了一些地址,可以用一下,不保证长期有效 http://idea.goxz.gq  ...

  10. element ui 查询过滤

    1.搜索框v-model="searchText" 2.data 声明searchText:"" 3.el-table:data="tables&qu ...