基本用法

例如:

names.forEach((name)->System.out.println(name));
names.forEach(System.out::println);//可以通过这种方式直接调用println

基本语法; (Type1 param1,Type2 param2,...)->{statment1, statment2... return statmentM;}

一般来讲,这个其实是接口或抽象类的简化。但是不是所有的类都可以使用Lambda的。

只有声明了函数式接口:public @interface FunctionalInterface才可以被Lambda赋值。这个就是可以简写的原因。通过函数式接口可以直接定位到这个类的某一个函数,然后就可以省略函数名等一系列要素.

例如:

(String name)->{
System.out.println(name);
return ;
}

这个是基础型,还有许多简化型:

  • 参数类型可以省略。例如上面可以把String省略,因为一般编译器都可以判断出来
  • 当参数只有一个时,可以省略小括号(但是私以为还是写上的好,为了统一)
  • 只有一条语句时,可以省略大括号。并且如果return没有返回值,也可以省略。也就是最前面第一个例子的写法。
  • 也可以只包含一个普通表达式。语法:(Type val1,Type val2...)->(expression)。例如:(int a, int b)->(a*b+2)

用Lambda代替内部类

例:

new Thread(()->System.out.println("Hello world!")).start();//方法1

Runnable race = ()->System.out.println("Hello world!");//方法2
new Thread(race).start();

上面这个例子完整写法是:

new Thread(
new Runnable()
{ //这是一个Runnable的匿名类
public void run()
{
System.out.println("Hello world!");
}
}//匿名类定义结束
)

至于匿名内部类,可以参考

省去new和类名/接口名。并且直接实现run方法。此外()代表的是接口内部方法的参数,因为run()没有参数,所以这里也不写

forEach()和排序

forEach定义: forEach(Consumer<? super T> action);

其中action实例必须实现Comsumer接口的accept(T t)方法。action指定具体的行为。

从jdk5开始,集合都实现了Iterable接口。也就是可以使用forEach()

例如:names.forEach((name)->System.out.println(name+","));

上面的Lambda表达式相当于Consumer的匿名对象。

排序
实际上就是简化了Comparator接口或者其他有关排序接口的写法。例如:

Comparator<String> sortByName = (String s1,String s2)->(s1.compareTo(s2));
Collections.sort(names,sortByName);

或者
Collections.sort(names,(String s1,String s2)->(s1.compareTo(s2)));

和streamapi联合

Stream接口是JDK8开始提供的,它可以充当Java集合的适配器。

方法:

  • filter(Predicate<? super T> predivate); 返回包含符合条件元素的流
  • forEach(Consumer<? super T> action); 遍历集合中的元素
  • limit(long maxSize): 返回maxSize个数的元素
  • max(Comparator<? super T> comparator): 根据规则返回最大的元素
  • min(Comparator<? super T> comparator)
  • sorted(): 对集合中的元素自然排序
  • sorted(Comparator<? super T>
  • mapToInt(ToIntFunction<? super T> comparator): 返回一个intStream型对象
  • mapToLong(ToLongFunction<? super T> mapper)
  • toArray(): 返回包含集合所有元素的对象数组

Lambda表达式变量作用域

Lambda可以访问外部类的所有变量。还可以使用this,这里this引用的是外部类。例如:

public class A
{
int var1 = 0;
public void test()
{
String[] data = {"Tom", "Mike", "Mary"};
List<String> names = Arrays.asList(data);
char var2 = ',';
names.forEach((name)->
{
var1++;
System.out.println(this.var1+":"+name);
}
}

public static void main(String[] args)
{
new A().test();
|
|

但是要注意一点,只能使用final修饰或者程序中不会改变的局部变量。这个类似于匿名内部类(实际上Lambda有匿名内部类的功能)。