lambda表达式基础
一、Lambda表达式基础入门
1.Lambda表达式简介
1.lambda是什么?
Lambda是java 8添加的一个新的特性。说白了Lambda就是一个匿名函数。
2.为什么要使用Lambda?
使用Lambda表达式可以对一个接口进行非常简洁的实现。
package com.example.lambda;
public class Program {
public static void main(String[] args) {
// 实现方法的三种方式
// 1.使用接口实现类
Comparator comparator = new MyComparator();
// 2.匿名内部类
Comparator comparator1=new Comparator() {
@Override
public int compare(int a, int b) {
return a-b;
}
};
// 3.Lambda表达是实现
Comparator comparator2=(a,b)->(a-b);
// 调用实现类
System.out.println("1----"+comparator.compare(3, 1));
// 调用匿名内部类
System.out.println("2----"+comparator1.compare(4, 2));
// 直接调用接口
System.out.println("3----"+comparator2.compare(5, 3));
}
}
// 創建类,实现接口
class MyComparator implements Comparator {
@Override
public int compare(int a, int b) {
return a - b;
}
}
// 创建接口
interface Comparator {
int compare(int a, int b);
}
3.Lambda对接口的要求
虽然可以使用Lambda表达式对某些接口进行简单的实现,但是并不是多有的接口都可以用Lambda表达式来实现。要求接口中定义的必须要实现的抽象方法只能是一个。
说明:在Java8中对接口增加了一个寻新的特性:default
接口中定义的default方法(带方法体的),是默认实现的,在实现类中不需要在去实现被default修饰的方法。
@FunctionalInterface 修饰函数式接口的,接口中的抽象方法只有一个。在使用lambda表达式实现接口时,通常在接口上加@FunctionalInterface注解。
@FunctionalInterface
interface Comparator {
int compare(int a, int b);
}
二、Lambda表达式基础语法
1.定义六个接口
2.基于Lambda表达式实现接口,并验证
public class Syntax1 {
/* Lambda表达式的基础语法
* 1.Lambda是一个匿名函数
* 2.组成:参数列表 lanmda运算符 方法体
* ():用来描述参数列表
* ->:Lambda运算符,读作 goes to
* {}":用来描述方法体
*/
public static void main(String[] args) {
// 无返回值,无参数
NoneReturnNoneParam lda1=()->{
System.out.println("lambda1无返回值,无参数");
};
// 调用
lda1.test();
// 无返回值,单个参数
NoneReturnSingleParam lda2=(int a)->{
System.out.println("lambda2无返回值,单个参数"+a);
};
// 调用
lda2.test(10);
//无返回值,多个参数
NoneReturnMultiParam lda3=(int a,int b)->{
System.out.println("lambda3无返回值,多个参数"+(a+b));
};
// 调用
lda3.test(2,3);
//有返回值,无参数
SingleReturnNoneParam lda4=()->{
System.out.println("lambda4有返回值,无参数");
return 100;
};
// 调用
System.out.println( lda4.test());
// 有返回值,单个参数
SingleReturnSingleParam lda5=(int a)->{
return a;
};
System.out.println("lambda5有有返回值,单个参数"+lda5.test(6));
}
}
三、Lambda表达式语法精简
package com.example.lambda.syntax;
public class Syntax2 {
public static void main(String[] args) {
// -------------------------语法精简-------------------------
/*------------1.参数类型------------
* 由于在接口的抽象方法中,已经定义了参数的数量和类型,所在在Lambda表达式中,参数的类型可以省略
* 备注:如果要省略参数类型,则每一个参数类型都要省略。
*/
NoneReturnMultiParam lda1 = (a, b) -> {
System.out.println(a + b);
};
/*------------2.参数小括号----------
*如果参数列表中,参数的数量只有一个,此时小括号可以省略
*/
NoneReturnSingleParam lda2 = a -> {
System.out.println(a);
};
/*------------3.方法大括号----------
* 如果方法体中只有一条语句,此时方法大括号可以省略
*/
NoneReturnNoneParam lda3 = () -> System.out.println("ad3");
/* 4.如果方法体中唯一的一条语句是一个返回一句,则在省略大括号的同时,也要省略"return" */
SingleReturnMultiParam ld4=(a,b)->a+b;
}
}
四、Lambda表达式语法进阶
public class Syntax3 {
public static void main(String[] args) {
/*----------------方法引用--------------
*可以快速的将Lambda表达式的实现指向一个已经实现的方法
*语法:方法的隶属者::方法名
*注意:
* 1.参数数量和类型一定要和接口中定义的一致
* 2.返回值的类型一定要和接口中定义的一致
*/
// 方法引用,引用了change方法的实现
SingleReturnSingleParam lda = Syntax3::change;
// 同上
SingleReturnSingleParam lda2 = a -> change(a);
// 测试
System.out.println(lda.test(10));
System.out.println(lda2.test(20));
}
private static int change(int a) {
return a;
}
}
五、构造方法的引用
public class Syntax4 {
public static void main(String[] args) {
// lambda创建person类
PersonCreate p=()->new Person();
// 方法引用:无参构造
PersonCreate p1=Person::new;
// 方法引用:有参构造
PersonCreate1 p2=Person::new;
// 测试
// 总结:调用不同参数的构造方法,取决于接口中的抽象方法的入参的定义
System.out.println(p.getPerson().toString());
System.out.println(p1.getPerson().toString());
System.out.println(p2.getPerson("liting", 18).toString());
}
}
@FunctionalInterface
interface PersonCreate{
Person getPerson();
}
@FunctionalInterface
interface PersonCreate1{
Person getPerson(String name,int age);
}
六、综合练习
1.ArrayList集合排序(无序可重复)
public class Exec {
public static void main(String[] args) {
// 集合排序
// 需求:一直在一个ArrayList中由若干个Person对象,将这些Person对象按照年龄进行升序排序
List<Person> list=new ArrayList<Person>();
list.add(new Person("aaa",2));
list.add(new Person("bbb",6));
list.add(new Person("ccc",4));
list.add(new Person("ddd",3));
Comparator<Person>person=(o1,o2)->Integer.valueOf(o1.getAge()).compareTo(o2.getAge());
list.sort(person);
/*list.sort(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return Integer.valueOf(o1.getAge()).compareTo(o2.getAge());
}
});*/
System.out.println(list.toString());
}
}
2.TreeSet集合排序(默认有序可不重复)
public class Exec2 {
public static void main(String[] args) {
// 使用TreeSet来实现Comparator接口,并实例化一个treeSet对象
TreeSet<Person> set =new TreeSet<Person>((o1,o2)->{
// set自动去重,如果等于0,会去掉重复数据
return o1.getAge() >=o2.getAge()?1:-1;
});
set.add(new Person("aaa",2));
set.add(new Person("bbb",6));
set.add(new Person("ccc",4));
set.add(new Person("ddd",3));
System.out.println(set.toString());
}
}
3.集合遍历
public class Exec3 {
public static void main(String[] args) {
/*------------集合遍历---------*/
List <Integer> list= new ArrayList<>();
Collections.addAll(list, 1,2,3,4,5,6);
// 方法引用输出
list.forEach(System.out::println );
// lambda表达式输出
list.forEach(ele->{
if(t%2==0){
System.out.println(t);
}
});
/*------------forEach实现思路---------*/
1.实现accept方法
Consumer<Integer> action = new Consumer<Integer>() {
@Override
public void accept(Integer t) {
if(t%2==0){
System.out.println(t);
}
}
};
// list.forEach(action);
2.list.forEach(action)源码(接口),Consumer<? super T> action 看做是accept方法的实现,而不是入参。调用forEach方法后,会遍历list,调用accept方法。
-------接口
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
----接口实现类
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int expectedModCount = modCount;
@SuppressWarnings("unchecked")
final E[] elementData = (E[]) this.elementData;
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
action.accept(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
/*-------------------------------遍历map------------------------*/
Map<Integer,String> map = new HashMap<>();
map.put(1, "aaa");
map.put(2, "bbb");
map.put(3, "ccc");
map.forEach((k,v)->{
System.out.println(k+"--"+v);
});
}
}
/*------------forEach实现思路---------*/
// 实现BiConsumer中accept方法
BiConsumer<Integer, String> consumer= new BiConsumer<Integer, String>() {
@Override
public void accept(Integer t, String u) {
System.out.println(t+"---"+t);
}
};
map.forEach(consumer);
/*------------forEach源码解析--------*/
接口
default void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
action.accept(k, v);
}
}
实现类
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
Node<K,V>[] tab;
if (action == null)
throw new NullPointerException();
if (size > 0 && (tab = table) != null) {
int mc = modCount;
for (int i = 0; i < tab.length; ++i) {
for (Node<K,V> e = tab[i]; e != null; e = e.next)
action.accept(e.key, e.value);
}
if (modCount != mc)
throw new ConcurrentModificationException();
}
}
4.removeIf删除集合元素
public class Exer4 {
public static void main(String[] args) {
List<Person> list=new ArrayList<Person>();
list.add(new Person("aaa",2));
list.add(new Person("bbb",6));
list.add(new Person("ccc",4));
list.add(new Person("ddd",3));
//迭代器遍历
Iterator<Person> l=list.iterator();
while(l.hasNext()){
Person p = l.next();
if(p.getAge()>5){
l.remove();
}
}
System.out.println(list.toString());
// 将集合中的每一个元素都带入到test方法中,如果返回true,则删除这个元素
list.removeIf(p->p.getAge()>5);
/*--------------------实现思路-----------------*/
Predicate<Person> pre=new Predicate<Person>(){
@Override
public boolean test(Person t) {
if(t.getAge()>5){
return true;
}
return false;
}
};
list.remove(pre);
/*--------------------remove源码----------------*/
接口:
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
}
}