Lambda表达式

Lambda表达式简介

什么是lambda表达式?

lambda表达式是java8添加的一个新特性,是一个匿名函数。

为什么要使用lambda?

使用lambda可以实现对一个接口非常简洁的实现.

lambda对接口的要求?

虽然lambda可以对某些接口简单实现,但不是所有,要求接口所规定要实现的抽象方法只能有一个。

@FuncationalInterface修饰函数式接口(接口中的抽象方法只有一个)

代码演示
package lambdapractice;

/**
 * @author hpc
 * @create 2021/1/29 19:57
 */
public class Program {
    public static void main(String[] args) {
        // 1.实例化Comparator
        Comparator comparator1 = new MyComparetor1();
        comparator1.compare(3,4);

        // 2.使用内部类
        Comparator comparator2 = new Comparator() {
            @Override
            public int compare(int a, int b) {
                return a - b;
            }
        };

        // 3.使用lambda实现Comparator接口
        Comparator comparator3 = (a,b) -> a - b;
    }
}

class MyComparetor1 implements Comparator{

    @Override
    public int compare(int a, int b) {
        return a - b;
    }
}

interface Comparator {
     int compare(int a, int b);
}

Lambda基础语法

代码1
@FunctionalInterface
public interface LambdaNoneReturnNoneParameter {
    void test();
}

@FunctionalInterface
public interface LambdaSingleReturnMutipleParameter {
    int test(int a, int b);
}

.....
代码2
public class Syntax1 {
    public static void main(String[] args) {
        //  Lambda表达式的参数列表和方法体
        //  ():用来描述参数列表
        //  {}:用来描述方法体
        //  ->:介于参数列表和方法体之间的lambda符号,读作 goes to

        //  无参无返回
        LambdaNoneReturnNoneParameter lambda1 = () -> System.out.println("Hello World!");
        lambda1.test();

        //  无返回,单参数
        LambdaNoneReturnSingleParameter lambda2 = (int a) -> {
            System.out.println(a);
        };
        lambda2.test(6);

        //  有返回值
        LambdaSingleReturnNoneParameter lambda3 = () -> {
            System.out.println("lambda3");
            return 4;
        };
        int result = lambda3.test();
        System.out.println(result);
    }
}

Lambda语法精简

语法精简
public class Syntax2 {
    public static void main(String[] args) {
        // 语法精简
        /**
         * 由于在接口中已近定义了参数的类型,
         * 所以在实现中可以省略类型,但是省略都得省略。
         */
        LambdaNoneReturnMutipleParameter lambda1 = (a, b) -> {
            System.out.println("省略参数类型");
        };
        lambda1.test(1,2);

        /**
         * 如果在参数中,参数的个数只有一个
         * 那么,小括号可以省略。
         */
        LambdaNoneReturnSingleParameter lambda2 = n -> {
            System.out.println("省略小括号");
        };
        lambda2.test(2);

        // 如果方法体中只有一条语句,那么大括号可以省略。
        //但是如果唯一的一条语句是return,则在省略大括号时也必须省略return
        LambdaSingleReturnNoneParameter lambda3 = () -> 3;

    }
}
方法引用
public class Syntax3 {
    public static void main(String[] args) {
        //  lambda方法引用
        /**
         * 当需要多次实现同一个逻辑时,可以把该逻辑写在另一个方法中
         * 然后去调用。但是要注意,另一个方法的参数和返回值都要和接口一致
         */
        LambdaSingleReturnMutipleParameter lambda1 = (a, b) ->  a + b;
        System.out.println(lambda1.test(1,2));
        //引用方式1
        LambdaSingleReturnMutipleParameter lambda2 = (a, b) -> function(a, b);
        System.out.println(lambda2.test(1,2));
        //  引用方式2   方法的隶属者::方法名

        LambdaSingleReturnMutipleParameter lambda3 = Syntax3 :: function;
    }
    public static int function(int x, int y) {
        return x + y;
    }
}  
构造方法的引用
public class Person {
    public String name;
    public int  age;

    public Person() {
        System.out.println("无参构造方法调用了");
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("有参构造方法调用了");
    }
}
------------------------------------------
public class Snytax4 {
    public static void main(String[] args) {
        //  构造方法的调用
        // 1.正常写
        PersonCreater person1 = () -> new Person();
        person1.getPerson();
        PersonCreater2 person2 = (String name, int age) -> new Person(name,age);
        person2.getPerson("xiaohong", 17);
        System.out.println("--------");

        // 2.方法调用
        PersonCreater person3 = Person::new;//Person类中有两个构造方法,PersonCreater接口实现时只能调用无参的构造方法。
        person3.getPerson();
        PersonCreater2 person4 = Person::new;//Person类中有两个构造方法,PersonCreater2接口实现时只能调用有参的构造方法。
        person4.getPerson("xiaoming" ,16);
    }
}
interface PersonCreater {
    Person getPerson();
}
interface PersonCreater2 {
    Person getPerson(String name, int age);
}

案例

对person进行排序
//  使用lambda实现集合排序
public class Exercise1 {
    public static void main(String[] args) {
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("a", 4));
        list.add(new Person("b", 5));
        list.add(new Person("c", 6));
        list.add(new Person("d", 7));

        //  以前的写法
        /*Comparator<? super Person> comparator = new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o2.age - o1.age;//  实现从大到小排序。
            }
        };
        list.sort(comparator);*/

        //  使用lambda的写法
        //  (p1, p2) -> p2.age - p1.age  就是一个函数式接口的实例化对象,主要任务是写实现该接口的逻辑。
        list.sort((p1, p2) -> p2.age - p1.age);
        System.out.println(list);
    }
}
TreeSet添加Person
public class Exercise2 {
    public static void main(String[] args) {
        //  treeset传入Person对象
        /**
         * treeset 传入对象时会进行排序,去重。所以要么传入的对象
         * 必须实现Comparator接口,要么实例化treeset对象时传入
         * Comparator对象。
         */
        TreeSet<Person> treeset = new TreeSet<>((p1,p2) -> {
            if (p1.age >= p2.age) return -1;
            else return 1;
        });

        treeset.add(new Person("a",1));
        treeset.add(new Person("b",2));
        treeset.add(new Person("c",3));
        treeset.add(new Person("d",4));
        treeset.add(new Person("e",4));

        System.out.println(treeset);
    }
}
自定义forEach
//  自定义forEach
public class Exercise3 {
    public static void main(String[] args) {
        ArrayList<Integer> arraylist = new ArrayList<>();
        Collections.addAll(arraylist,1,2,3,4,5,6);

        /*@FunctionalInterface
            public interface Consumer<T> {
            void accept(T t);}
        四大函数式接口之一:消费式接口,实现该接口的抽象方法就是要完成对该接口抽象方法中的参数进行操作。*/

        //  操作1,偶数打印
        arraylist.forEach(ele -> {
            if (ele%2 == 0) {
                System.out.println(ele);
            }
        });

         //  操作2,直接调用System.out中的println函数打印
        arraylist.forEach(System.out::println);
    }
}
集合中的删除
public class Exercise4 {
    public static void main(String[] args) {
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("a", 4));
        list.add(new Person("b", 5));
        list.add(new Person("c", 6));
        list.add(new Person("d", 7));

        // 删除age大于5的元素

        // 传统实现
        // 对几何元素遍历remove时,推荐使用迭代器迭代
        /*Iterator<Person> iterator = list.iterator();
        while (iterator.hasNext()) {
            Person p = iterator.next();
            if (p.age > 5)
                iterator.remove();//不能使用list.remove(p),这会出现数据混乱。
        }
        System.out.println(list);*/

        //  使用Lambda表达式实现
        /*这是removeIf函数要传入的接口参数。
        @FunctionalInterface
        public interface Predicate<T> {
            boolean test(T t);
            }*/
        //  test方法返回true则删除元素,使用lambda实现该函数式接口
        list.removeIf(t -> t.age > 5);
        System.out.println(list);
    }
}
线程的实现
public class Exercise5 {
    public static void main(String[] args) {
        Thread mythread1 = new Thread(() -> {
            for (int i = 1;i <= 5;i++) {
                System.out.println(i);
            }
        });

        Thread mythread2 = new Thread(() -> {
            for (int k = 6;k <=10;k++ ) {
                System.out.println(k);
            }
        });
        mythread1.start();
        mythread2.start();
    }
}

系统内置的函数式接口

前四个常用。

  • Predicate :参数 T,返回值 boolean
  • Consumer :参数 T,返回值 void
  • Function<T,R> :参数 T,返回值 R
  • Supplier :无参,返回值 R
  • UnaryOperator :参数 T,返回值 T
  • BiFunction<T,U,R> :参数 T,U,返回值 R
  • BinaryOperator :参数 T,T,返回值 T
  • BiPredicate<T,U> :参数 T,U,返回值 boolean
  • BiConsumer<T,U,R> :参数 T,U,返回值 void
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值