– 面向过程程序语言:参数传递是基本类型的变量
– 面向对象语言:

  • 传递基本类型的变量
  • 传递对象变量

– 函数式程序语言设计:传递方法 / 代码块
即允许把函数作为一个方法的参数(函数作为参数传递进方法中)–>> Lambda 表达式–> Java 8 发布的新特性,引入了一个新的操作符 " -> " 该操作符称为箭头操作符或 Lambda 操作符

使用 Lambda 表达式可以使代码变的更加简洁紧凑。

lambda 表达式的语法格式:
  • 参数,箭头,一个表达式
(parameters) -> expression
  • 参数,箭头,{多个语句}
(parameters) ->{ statements; }
lambda表达式的重要特征:
  • 类似匿名方法,一个没有名字的方法
  • 不需要声明参数类型,编译器可以统一识别参数值
  • 坚决不声明返回值类型
  • 没有 public/protected/private/static/final 等修饰符
  • 单句表达式,将直接返回值,不用大括号
  • 带 return 语句, 算多句,必须用大括号(不用void()声明)
    如果有返回值,返回值类型会在上下文推断出来的,无需声明,只在某几个分支有返回值,是不合法的
x ->
{
	if(x>0)
		return x+1;
};
数组字符串排序实例
package com.lambda;

import java.util.Arrays;
//doc:StringOrderTest.java
public class StringOrderTest {

	public static void main(String[] args) {
		String[] planets = new String[] { 
				"Mercury", "Venus", "Earth", "Mars", 
				"Jupiter", "Saturn", "Uranus","Neptune" };	

		System.out.println(Arrays.toString(planets));		//返回指定数组的内容的字符串表示形式
		System.out.println("=======================");
		System.out.println("使用长度从小到大的比较器:");
		Arrays.sort(planets, new LengthAscComparator());	//按照数字顺序排列指定的数组
		
		System.out.println(Arrays.toString(planets));
		System.out.println("使用长度从大到小的比较器:");
		Arrays.sort(planets, new LengthDescComparator());
		System.out.println(Arrays.toString(planets));		

		System.out.println("=======================");
		System.out.println("使用Lambda, 长度从小到大:");
		Arrays.sort(planets, 
				(String first, String second) 
				   -> first.length() - second.length());
		System.out.println(Arrays.toString(planets));
		
		System.out.println("使用Lambda, 长度从大到小:");
		Arrays.sort(planets, (first, second) -> (-1) * (first.length() - second.length()));
		System.out.println(Arrays.toString(planets));
		
		System.out.println("使用Lambda, 长度从大到小:");
		Arrays.sort(planets, 
			(String first, String second) -> {
				int result = (-1) * (first.length() - second.length());
				return result;
			}
		);
		System.out.println(Arrays.toString(planets));
		
		System.out.println("=======================");
		//无参数,仅保留括号,箭头和表达式
		new Thread(
			() -> {
				int sum = 0;
				for (int i = 1; i <= 100; i++) {
					sum = sum + i;
				}
				System.out.println("总和:" + sum);
			}
		).start();

	}
}
package com.lambda;

import java.util.Comparator;		//比较器,Comparator接口实现自定义排序
//doc:LengthAscComparator.java
public class LengthAscComparator implements Comparator<String> {
	public int compare(String first, String second) {
		//获取2个字符串长度
		int len1 = (first==null? 0 : first.length());
		int len2 = (first==null? 0 : second.length());
		
		//如果len1 == len2,返回0,表示两个字符串相等
		//如果len1 >  len2,返回正数,表示first>second
		//如果len1 <  len2,返回负数,表示first<second
		return len1 - len2;
	}
}
package com.lambda;

import java.util.Comparator;
//doc:LengthDescComparator.java
public class LengthDescComparator implements Comparator<String> {
	public int compare(String first, String second) {
		//获取2个字符串长度
		int len1 = (first==null? 0 : first.length());
		int len2 = (first==null? 0 : second.length());
		
		//如果len1 == len2,返回0,表示两个字符串相等
		//如果len1 >  len2,返回正数,表示first>second
		//如果len1 <  len2,返回负数,表示first<second
		return (-1) * (len1 - len2);
	}
}

运行结果:

java 箭头符号 java 箭头表达式_lambda

函数式接口 (Functional Interface)
  • 只包含一个抽象方法的接口
  • 可以包括其他的 default 方法、 static 方法、 private 方法
  • 由于只有一个未实现的方法,所以 Lambda 表达式可以自动填上这个尚未实现的方法
  • 采用 Lambda 表达式,可以自动创建出一个( ( 伪) ) 嵌套类的对象( ( 没有实际的嵌套类 class 文件产生) ),然后使用,比真正嵌套类 更加轻量 ,更加简洁高效

上例中 - - >> Lambda 表达式( ( 匿名函数) ) 自动成为接口方法的实现

Lambda 表达式:自动填充上Comparator的compare方法,变成一个Comparator的子对象

java 箭头符号 java 箭头表达式_编程语言_02


若不用Lambda 表达式,可采用匿名内部类:相对不够简洁,还会产生额外的嵌套类的class文件(含$符号的文件)

java 箭头符号 java 箭头表达式_java 箭头符号_03

java.utils包下的Comparator接口。该接口代表一个比较器,java数组工具类和集合工具类中提供对sort方法排序就是使用 Comparator接口来处理排序的。
Comparator接口中有一个方法int compare(T o1, T o2)。这个方法返回值是int类型,
如果返回值小于0,说明比较结果是o1<o2,
如果返回值等于0,说明比较结果是o1=o2,
如果返回值大于0,则说明比较结果是o1>o2。

自定义函数式接口时,可写上系统自带的函数式接口注解,用于编译器检查:

@FunctionalInterface
函数式接口的优缺点:
  • 只带有一个未实现的方法,内容简单
  • 大量重复性的函数式接口,使得源码膨胀

为避免源码膨胀,可采用系统自带的函数式接口

  • 涵盖大部分常用的功能,可以重复使用
  • 位于 java.util.function 包中
Java内置的四大函数式接口:

java 箭头符号 java 箭头表达式_字符串_04

方法引用: Method Reference

Lambda 表达式支持传递现有的类库函数

java 箭头符号 java 箭头表达式_字符串_05