Java8新特性----Lambda表达式详细探讨

Posted 大忽悠爱忽悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java8新特性----Lambda表达式详细探讨相关的知识,希望对你有一定的参考价值。


Lambda表达式

​ Lambda是一个匿名函数,可以理解为一段可以传递的代码(将代码像数据一样传递);可以写出更简洁、更灵活的代码;作为一种更紧凑的代码风格,是Java语言表达能力得到提升


入门演示

案例1

public class TestMain
{
    //使用匿名内部类完成比较
    @Test
    public void test()
    {
        //比较器                 匿名内部类,创建该接口的一个实现类
        Comparator<People> com=new Comparator<People>() {
            @Override
            public int compare(People o1, People o2) {
                return o1.getAge()-o2.getAge();
            }
        };
        //TreeSet的特点是可排序、不重复
        TreeSet<People> ts=new TreeSet<>(com);
        ts.add(new People("大忽悠",20));
        ts.add(new People("小忽悠",18));
        ts.add(new People("大大大",22));
        ts.add(new People("小朋友",17));
        ts.forEach(System.out::println);
    }

    //lambda表达式替代匿名内部类
    @Test
    public void test1()
    {
        //比较器
        Comparator<People> com=(p1,p2)-> p1.getAge()-p2.getAge();
        //TreeSet的特点是可排序、不重复
        TreeSet<People> ts=new TreeSet<>(com);
        ts.add(new People("大忽悠",20));
        ts.add(new People("小忽悠",18));
        ts.add(new People("大大大",22));
        ts.add(new People("小朋友",17));
        ts.forEach(System.out::println);
    }
}

如何解决 cannot be cast to java.lang.Comparable问题?

如何解决 cannot be cast to java.lang.Comparable问题?


案例2

要求对下面的代码进行优化:

public class TestMain
{
    List<People> peopleList= Arrays.asList(
            new People("1号",18,3000),
            new People("2号",21,4000),
            new People("3号",19,5000),
            new People("4号",20,3500)
    );
    //获取年龄大于18的
    public List<People> getAgeOver18()
    {
        List<People> list=new ArrayList<>();
        for (People p:peopleList)
        {
            if(p.getAge()>18)
                list.add(p);
        }
        return list;
    }

    //获取工资大于3000的
    public List<People> getMoneyOver3000()
    {
        List<People> list=new ArrayList<>();
        for (People p:peopleList)
        {
            if(p.getMoney()>3000)
                list.add(p);
        }
        return list;
    }
    @Test
    public void test()
    {
        List<People> ageOver18 = getAgeOver18();
        ageOver18.forEach(System.out::println);
        System.out.println("======================================");
        List<People>  moneyOver3000=getMoneyOver3000();
        moneyOver3000.forEach(System.out::println);
    }
}

优化方式一 : 策略设计模式

声明一个接口MyPrediect

public interface MyPrediect<T>
{
  public boolean test(T t);
}

接口的实现类一FilterPeoAge,负责过滤年龄:

public class FilterPeoAge implements MyPrediect<People>{
    @Override
    public boolean test(People people) {
        return people.getAge()>18;
    }
}

接口实现类二FilterPeoMoney,负责过滤金钱

public class FilterPeoMoney implements MyPrediect<People>{
    @Override
    public boolean test(People people) {
        return people.getMoney()>3000;
    }
}

测试演示:

public class TestMain
{
    List<People> peopleList= Arrays.asList(
            new People("1号",18,3000),
            new People("2号",21,4000),
            new People("3号",19,5000),
            new People("4号",20,3500)
    );
     public List<People> FilterPeo(List<People> list,MyPrediect<People> mp)
     {
         List<People> peopleList=new ArrayList<>();
         for (People p:list)
         {
             if(mp.test(p))
                 peopleList.add(p);
         }
         return peopleList;
     }

    @Test
    public void test()
    {
        List<People> peopleList = FilterPeo(this.peopleList, new FilterPeoAge());
        peopleList.forEach(System.out::println);
        System.out.println("===========================");
        List<People> peopleList1 = FilterPeo(peopleList, new FilterPeoMoney());
        peopleList1.forEach(System.out::println);
    }
}


当我们还需要安装某个策略进行过滤时,只需要实现接口,完成相应策略过滤逻辑编写即可


优化方式二: 策略设计模式+匿名内部实现接口,减少创建实体类的麻烦

public class TestMain
{
    List<People> peopleList= Arrays.asList(
            new People("1号",18,3000),
            new People("2号",21,4000),
            new People("3号",19,5000),
            new People("4号",20,3500)
    );
     public List<People> FilterPeo(List<People> list,MyPrediect<People> mp)
     {
         List<People> peopleList=new ArrayList<>();
         for (People p:list)
         {
             if(mp.test(p))
                 peopleList.add(p);
         }
         return peopleList;
     }

    @Test
    public void test()
    {
        List<People> peopleList = FilterPeo(this.peopleList, new MyPrediect<People>() {
            @Override
            public boolean test(People people) {
                return people.getAge()>18;
            }
        });
        peopleList.forEach(System.out::println);
        System.out.println("===========================");
        List<People> peopleList1 = FilterPeo(peopleList, new MyPrediect<People>() {
            @Override
            public boolean test(People people) {
                return people.getMoney()>3000;
            }
        });
        peopleList1.forEach(System.out::println);
    }
}


优化方式三: lambda表达式

public class TestMain
{
    List<People> peopleList= Arrays.asList(
            new People("1号",18,3000),
            new People("2号",21,4000),
            new People("3号",19,5000),
            new People("4号",20,3500)
    );
     public List<People> FilterPeo(List<People> list,MyPrediect<People> mp)
     {
         List<People> peopleList=new ArrayList<>();
         for (People p:list)
         {
             if(mp.test(p))
                 peopleList.add(p);
         }
         return peopleList;
     }

    @Test
    public void test()
    {
        List<People> peopleList = FilterPeo(this.peopleList, (people)-> people.getMoney()>4000);
        peopleList.forEach(System.out::println);
    }
}


优化方式四: stream流

public class TestMain
{
    List<People> peopleList= Arrays.asList(
            new People("1号",18,3000),
            new People("2号",21,4000),
            new People("3号",19,5000),
            new People("4号",20,3500)
    );
     public List<People> FilterPeo(List<People> list,MyPrediect<People> mp)
     {
         List<People> peopleList=new ArrayList<>();
         for (People p:list)
         {
             if(mp.test(p))
                 peopleList.add(p);
         }
         return peopleList;
     }

    @Test
    public void test()
    {
        peopleList.stream().filter(people -> people.getMoney()>3000).limit(2).forEach(System.out::println);
    }
}


Lambda语法

- 操作符:->
- 左侧:参数列表
- 右侧:执行代码块 / Lambda


即lambda是对接口的抽象方法的实现,可能有人会问,如果接口中抽象方法存在多个,那lambda是对哪个抽象方法的实现呢?

其实lambda需要一个函数式接口的支持,即当前接口只有一个抽象方法


语法格式一 : 无参数,无返回值

    @Test
  public void test()
  {
      Runnable runnable = new Runnable() {
          @Override
          public void run() {
              System.out.println("方法执行中.....");
          }
      };
      runnable.run();
      System.out.println("----------------------");
      Runnable r1=()-> System.out.println("r1执行中....");
      r1.run();
  }


注意: 局部内部类与局部变量

局部内部类在JDK8之前只能使用成员变量和被final修饰的局部变量。JDK8之后,局部内部类如果使用局部变量那么局部变量默认被final修饰,但如果局部变量被重新赋值,那么局部内部类将不能在使用。具体看下例子:

	public void show() {
		int j = 0;   //jdk1.8后默认被final修饰。1.8之前局部内部类只能访问成员变量,和被final修饰的局部变量
		class A{
			public void showA<

以上是关于Java8新特性----Lambda表达式详细探讨的主要内容,如果未能解决你的问题,请参考以下文章

Java8新特性,你一定能学会的超详细保姆级源码笔记,看完还不会请直接砍我

Java8新特性,你一定能学会的超详细保姆级源码笔记,看完还不会请直接砍我

Java8新特性,你一定能学会的超详细保姆级源码笔记,看完还不会请直接砍我

Java8新特性,你一定能学会的超详细保姆级源码笔记,看完还不会请直接砍我

java8 Lambda表达式详细讲解

java8 Lambda表达式详细讲解