精华内容
下载资源
问答
  •   梳理一下实现类、匿名类、内部类、匿名内部类、Lambda表达式以及优化Lambda表达式的关系,仅针对初学者。   自定义一个接口MyFunctionInterface,其中有且仅有一个抽象方法(接口中可以有其他非抽象方法内容)...

      梳理一下实现类、匿名类、内部类、匿名内部类、Lambda表达式以及优化Lambda表达式的关系,仅针对初学者。
      自定义一个接口MyFunctionInterface,其中有且仅有一个抽象方法(接口中可以有其他非抽象方法内容),代码实现为:

    /*
        函数式接口:有且只有一个抽象方法的接口,称之为函数式接口;
        当然接口中可以包含其他的方法(默认,静态,私有)。
     */
    public interface MyFunctionInterface {
    
        public abstract void method();
        
    }
    
    1. 实现类(创建实现类对象)
        实现接口MyFunctionInterface,重写其中的抽象方法;新建一个Java文件,实现类代码为:
    public class MyFunctionInterfaceImpl implements MyFunctionInterface {
    
        @Override
        public void method() {
            System.out.println("测试成功");
        }
        
    }
    

      新建一个测试类,代码为:

    public class Demo {
        public static void main(String[] args) {
        
            MyFunctionInterface mi = new MyFunctionInterfaceImpl();//多态
            mi.method();
            
        }
    }
    
    1. 匿名类(创建匿名实现类对象)
    public class Demo {
        public static void main(String[] args) {
        
            new MyFunctionInterfaceImpl().method();
            
        }
    }
    
    1. 内部类(不需要创建实现类对象)
    public class Demo {
        public static void main(String[] args) {
        
            MyFunctionInterface mi = new MyFunctionInterface() {
                @Override
                public void method() {
                    System.out.println("内部类测试成功");
                }
            };
            mi.method();
            
        }
    }
    
    1. 匿名内部类(不需要创建实现类对象)
    public class Demo {
        public static void main(String[] args) {
        
            new MyFunctionInterface() {
                @Override
                public void method() {
                    System.out.println("匿名内部类测试成功");
                }
            }.method();
            
        }
    }
    
    1. Lambda表达式
        因为接口MyFunctionInterface中有且仅有一个抽象方法,所以是函数式接口,可以使用Lambda表达式,代码实现:
    public class Demo {
        public static void main(String[] args) {
        
            MyFunctionInterface mi = () -> {
                System.out.println("Lambda表达式测试成功");
            };
            mi.method();
            
        }
    }
    
    1. 优化Lambda表达式
    public class Demo {
        public static void main(String[] args) {
        
            MyFunctionInterface mi = () -> System.out.println("优化Lambda表达式测试成功");
            mi.method();
            
        }
    }
    

      实际上,Lambda表达式常用作方法的参数或方法的返回值。
    当Lambda表达式作为方法的形参:

    public class Demo {
    
        public static void show(MyFunctionInterface myInter) {
            myInter.method();
        }
    
        public static void main(String[] args) {
            /*
            //先使用匿名内部类热热身
            show(new MyFunctionInterface() {
                @Override
                public void method() {
                    System.out.println("匿名内部类测试成功");
                }
            });//show方法执行myInter.method()之前,method方法已经重写,所以执行成功
            */
            //Lambda表达式
            show(() -> {
                System.out.println("Lambda表达式测试成功");
            });
            //优化的Lambda表达式
            show(()->System.out.println("优化的Lambda表达式测试成功"));
        }
    
    }
    

    当Lambda表达式作为方法的返回值(这里使用接口Comparator< String >举例):

    public class Demo {
        //定义一个方法,方法的返回值类型使用函数式接口Comparator
        public static Comparator<String> getComparator() {//接口Comparator<>只有一个抽象方法,所以可以使用Lambda表达式
            /*
            //先用匿名内部类热热身
            return new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    return o2.length()-o1.length();//按字符串降序排序
                }
            };
            */
            //方法的返回值类型是一个函数式接口,所有我们可以返回一个Lambda表达式(优化后的)
            return (o1, o2) -> o2.length() - o1.length();
        }
    
        public static void main(String[] args) {
            String[] arr = {"cc","bbb","aaaa"};//首先按字符个数、再按字母进行降序
            Arrays.sort(arr,getComparator());//sort(T[] a, Comparator<? super T> c) 根据指定的比较器引发的顺序对指定的对象数组进行排序。
            System.out.println(Arrays.toString(arr));//打印结果:[aaaa, bbb, cc]
        }
    }
    
    展开全文
  • lambda表达式java 在本文中,我们提供了全面的Lambda Expressions Java教程。 1. Lambda Expressions Java教程–简介 Lambda表达式被认为是Java 8中引入的最好的功能之一。Lambda表达式被认为是Java进入函数式...

    lambda表达式java

    在本文中,我们提供了全面的Lambda Expressions Java教程。

    1. Lambda Expressions Java教程–简介

    Lambda表达式被认为是Java 8中引入的最好的功能之一。Lambda表达式被认为是Java进入函数式编程世界的第一步 。 可以将其视为无需类即可创建的函数。 它也可以像参数一样传递,并且可以在需要时和根据需要执行。 Java Lambda表达式是匿名函数的简洁表示,可以将其传递。 具有单个功能的匿名类使用额外的语法进行了笨拙的演示。 这些表述旨在消除这种混乱。

    如前所述,Java Lambda表达式是无名函数 ,可以作为常量值进行传递。 这意味着它们可以出现在可能存在任何其他常数值的任何位置,但是通常作为参数写入某些其他函数。 考虑一个典型的例子,我们可以将比较函数传递给泛型排序函数,而不是麻烦地定义一个整个过程(并引起词法不连续和名称空间污染)来描述这种比较,我们只需传递一个lambda表达式描述了比较。 让我们看一下Lambda表达式的一些属性

    • 匿名:它仍然可以称为匿名,因为它没有明确的名称。
    • 简洁:正如前面提到的匿名类的情况,与匿名类相比,我们用Lambdas编写的代码要少得多。
    • 函数:Lambda更像是函数而不是方法。 这是因为方法属于类,而Lambda不属于。 但是就像方法一样,Lambda接受参数列表,具有主体并且还可以引发异常。
    • 可以传递:Lambda可以传递给其他函数,就像普通参数一样。

    为了消除可能由于我们上面提到的观点而引起的任何误解,lambda不会添加引入之前的更多功能。 它只是改善了我们编写代码的方式,并减少了很多样板代码。 该样板代码甚至与我们用来通过基础操作系统的多核性质进行代码识别的系统级编程有关。 让我们看看这种简单的语法糖如何使我们的工作在并行性,代码简洁性和紧凑性方面变得更加轻松。

    2.编写Lambda表达式

    在本节中,我们将看到Java Lambda表达式如何减少执行一些简单操作所需编写的代码行。 例如,我们将比较代码行数以构成比较器功能。 为了建立比较,我们将在这里创建一个简单的POJO类,一个Student类,其中包含Student ID(作为Long和name作为String参数:

    学生.java

     public class Student {   
        private Long id; 
        private String name; 
        // standard setters and getters  } 

    比较我们在应用程序中定义的POJO对象是一种非常通用的编程实践。 如果要比较两个Student类对象,则可以使Comparator像这样:

    匿名类的比较器

     Comparator<Student> byId = new Comparator<Student>() { 
        @Override 
        public int compare(Student s1, Student s2) { 
            return s1.getId().compareTo(s2.getId()); 
        }  }; 

    这是一个作为Anonymous类的简单Comparator实现,但我们发现使用Lambda进行处理时,相同的实现非常精确和干净。 让我们在这里看到使用Lambda表达式完成的相同任务:

    pom.xml

     Comparator<Student> byId = (s1, s2) -> s1.getId().compareTo(s2.getId()); 

    Lambda表达式上方也可以称为块Lambda表达式,因为它由>符号右侧的单个代码块组成。 它变得更加简洁小巧,这听起来很神奇,请参见以下代码片段:

    简洁的Lambda实现

     Comparator<Student> byId = Comparator.comparing(Student::getId); 

    这是建立比较器的好方法,而且也很简单。 对于上面我们进行的Block Lambda表达式,让我们对其进行分解以更好地理解:

    Lambda表达式Java-Lambda表达式
    Lambda表达
    • Lambda Expression以在此情况下传递给函数Comparator的参数列表开头
    • 箭头符号将Lambda Expression参数与Lambda主体分开
    • 主体清楚地将两个学生对象及其id进行比较,该表达式定义了Lambda返回值

    要注意的是,已编译的代码(即匿名类版本和Lambda表达式版本的字节码)将完全相同,因为Lambda表达式只是使代码清晰的语法。 尽管使用Lambda表达式有时可能会使代码的可读性降低。

    3. Lambda表达式与匿名类

    我们使用Lambda表达式编写的代码也可以使用Anonymous类编写,其实现方式与Lambda Expressions完全相同。 区别在于Lambda代码的简洁性。

    作为比较示例,让我们构造一个类和一个将Runnable作为输入的方法:

    可运行类

     public class RunnableInstance { 
         public static void doSomething(Runnable runnable){ 
             runnable.run(); 
         }  } 

    当我们使用Anonymous类制作Runnable时,其外观如下所示:

    可通过匿名类运行

     Runnable runnable = new Runnable() { 
         @Override 
         public void run() { 
             System.out.print( "Anonymous class implementation." ); 
         }  };  doSomething(runnable); 

    让我们尝试将上面的代码转换为Lambda表达式,看看如何得到干净的东西:

    可与Lambda一起运行

     Runnable runnable = () -> System.out.print( "Lambda Expression." );  doSomething(runnable); 

    如果我们不想多次使用可运行的实现,我们甚至可以避免进行引用:

    简洁的Lambda Runnable

     doSomething(() -> System.out.print( "Lambda Expression." )); 

    4.使用Lambda表达式进行并行编程

    每当我们谈论线程时,我们大多数人都会退后一步,考虑是否真的需要在我们的应用程序中实现线程以支持并行性,因为并行性本质上微不足道且难以管理。 当我们有一组项目时,我们实现了一个lambda,如:

    并行编程

     collection.map { // my lambda } 

    在这里,集合本身能够与提供的Lambda实现并行性,而不必自己执行线程。 这意味着,在多核环境中,Lambda可以在集合上进行流式传输时利用多个核。 就像我们考虑一个简单的例子一样:

    Lambda与并行流

     List<String> names = students.stream() 
             .map(s -> s.getName().toUpperCase()) 
             .collect(Collectors.toList()); 

    map函数可以在多核环境中并行运行,以一次处理多个对象,而无需我们做任何事情。 为此,仅需要执行此程序的操作系统必须是多核。 一旦满足此条件,我们可以确保可以在给定语句中并行化的任何操作都将自动完成。

    5.集合和流

    Collections框架是Java中最常用的Framework API之一。 集合允许我们将相似的对象收集到可以针对特定目的进行优化的数据结构中。 前面的所有示例都需要对象集合,因此,假设我们有一个Student类型的对象集合,就像我们之前定义的那样:

    学生集合

     List students = getStudentObjectCollection(); 

    我们从添加到Collection接口的新方法stream()开始。 由于所有集合都“扩展”集合,因此所有Java集合都继承了此方法:

    学生流

     List students = getStudentObjectCollection();  Stream stream = students.stream(); // a stream of student objects 

    尽管看起来很像,但Stream接口不是另一种常规的集合类型。 我们可以将Stream视为“数据流”抽象,它使我们能够转换或操纵其包含的数据。 与我们在Java中研究过的其他集合不同,Stream不允许我们直接访问其包含的元素。 尽管如果您想访问元素,我们总是可以将流转换为Java中的集合之一并实现我们的目的。

    出于演示目的,我们将看到如果我们必须计算我们的students集合中有多少个奇数ID对象,我们的代码将是什么样子。 首先,让我们看看如何在不使用流的情况下完成此操作:

    计数奇数

     long count = 0 ;  List students = getStudentObjectCollection();  for (Student s : students) { 
         if (s.getId() % 2 == 1 ) { 
             count++; 
         }  } 

    使用for循环,我们创建了一个计数器,每次在学生列表中遇到奇数ID时,该计数器都会递增。 我们已经为这种非常简单的任务写了数百遍这种类型的代码,它跨越多行。

    我们也可以在一行中使用Stream编写完全相同的代码:

    使用流

     List students = getStudentObjectCollection();  long count = students.stream().filter(student -> student.getId() % 2 == 1 ).count(); 

    这看起来比以前的for循环方法干净整洁吗? 一切都始于调用stream()方法,该方法将给定的集合转换为Stream,所有其他调用都链接在一起,因为Stream接口中的大多数方法都是在考虑到Builder模式的情况下设计的 。 对于那些不习惯使用这种方法进行链接的用户,可能更容易这样可视化:

    可视化流

     List students = getStudentObjectCollection();  Stream stream = students.stream();  stream = stream.filter(student -> student.getId() % 2 == 1 );  long count = stream.count(); 

    让我们将注意力集中在我们使用的Stream的两种方法中, filter()count()

    filter()方法采用要过滤集合的条件,该条件由一个lambda表达式表示,该表达式带有一个参数并返回一个布尔值:

    Lambda条件

     student -> student.getId() % 2 == 1 

    并非偶然,用于表示该表达式的功能接口filter()方法的参数filter()是谓词接口。 它只有一个抽象方法boolean test(T t)

    功能介面

     @FunctionalInterface  public interface Predicate { 
         boolean test(T t); 
         // non-abstract methods here  } 

    参数化类型T表示流中元素的类型,即Student对象。 过滤之后,剩下的就是调用count()方法。 没什么大不了的,它只是计算过滤发生后我们流中还剩下多少个对象(除了过滤之外,我们还可以有更多的东西)。 count()方法被视为“终端操作”,在调用该方法后,该流被称为“已消耗”且无法再使用。

    6. Lambda表达式的缺点

    尽管带有Lambda Expressions的代码看起来非常简洁,但是Lambdas也有一些缺点。 让我们在这里研究其中的一些:

    • 无法处理检查的异常 :任何引发检查的异常的代码都应包装在try-catch语句中。 但是,即使我们这样做,也不总是总是清楚抛出的异常发生了什么。
    • 性能问题 :由于JIT不能始终将forEach() + lambda优化到与普通循环相同的程度,因此Lambda可以在很小程度上影响性能。
    • 调试挑战 :显然,使用Lambdas时,代码并不总是那么简洁。 这使得堆栈跟踪代码中出现的异常和可读性变得有些困难。

    尽管Lambda有一些缺点,但是当您编写简洁的代码时,它们仍然是不错的伴侣。

    7.结论

    Java Lambda表达式在所有LISP,Perl,Python以及最新版本的C ++,Objective C,C#和Java 8中都出现(具有不同的语法),但值得注意的是,即使它可以处理传递的函数(或一些借口)作为参数。 它们是具有特定语义的语法元素,并且这些语义对运行时的要求比C所设计的要高。

    本课中 ,我们可以阅读有关Lambda表达式的更多信息,它与功能接口有很深的联系,还演示了将并行流与Lambda表达式配合使用的性能比较,并加深了对Lambda表达式如何与功能接口一起使用以及可以在简单语句中使用的理解。利用多核操作系统提供的并行性,而无需了解幕后工作的API。

    上次更新时间为2020年2月17日

    翻译自: https://www.javacodegeeks.com/lambda-expressions-java-tutorial.html

    lambda表达式java

    展开全文
  • Lambda表达式

    2021-07-31 22:12:24
    准备工作5.Lambda基本语法-测试6.Lambda基本语法-简化7.Lambda表达式常用示例7.1Lambda表达式引用方法7.2构造方法的引用7.3Lambda表达式创建线程7.4Lambda遍历集合7.5删除集合中的某个元素7.6集合内元素的排序 ...

    1.Lambda简介

    Lambda表达式是JDK8的一个新特性,可以取代大部分的匿名内部类,写出更优雅的java代码,尤其在集合的遍历和其他集合操作中可以极大地优化代码结构。
    JDK也提供了大量的内置函数式接口供我们使用,使得Lambda表达式的运用更加方便,高效。

    2.对接口的要求

    虽然使用Lambda表达式可以对某些接口进行简单的实现,但并不是所有的接口都可以使用Lambda表达式来实现。Lambda规定接口中只能有一个需要被实现的方法,不是规定接口中只能有一个方法。
    JDK8中有另一个新特性:default,被default修饰的方法会有默认实现,不是必须被实现的方法,所以不影响Lambda表达式的使用。

    3.@FunctionalInterface

    修饰函数式接口的,要求接口中的抽象方法只有一个。这个注解往往会和lambda表达式一起出现。
    作用:验证当前接口是否只有一个需要被实现的方法,如果不满足,就编译报错。
    所有它就是为lambda表达式而生的。

    @FunctionalInterface
    public interface MyInterface {
        void a();
        default void b(){
    
        };
    }
    

    4.Lambda基础语法-准备工作

    语法形式为() -> {},其中()用来描述参数列表,{}用来描述方法体,->为lambda运算符,读作(goes to)

    package lambda;
    
    public interface LambdaInterface {
    }
    
    
    /**
     * 无返回无参数
     */
    @FunctionalInterface
    interface NoReturnNoParam{
        void method();
    }
    
    /**
     * 无返回有一个参数
     */
    @FunctionalInterface
    interface NoReturnOneParam{
        void method(int a);
    }
    
    /**
     * 无返回有多个参数
     */
    @FunctionalInterface
    interface NoReturnMultiParam{
        void method(int a,int b);
    }
    
    /**
     * 有返回无参数
     */
    @FunctionalInterface
    interface ReturnNoParam{
        int method();
    }
    
    /**
     * 有返回有一个参数
     */
    @FunctionalInterface
    interface ReturnOneParam{
        int method(int a);
    }
    
    /**
     * 有返回有多个参数
     */
    @FunctionalInterface
    interface ReturnMultiParam{
        int method(int a,int b);
    }
    

    5.Lambda基本语法-测试

    package lambda;
    
    /**
     * @author 葡萄
     * 基础语法测试
     */
    public class LambdaTest01 {
        public static void main(String[] args) {
            //无参无返回
            NoReturnNoParam noReturnNoParam = () -> {
                System.out.println("ok");
                System.out.println("ok");
            };
            noReturnNoParam.method();
            //一个参数无返回
            NoReturnOneParam noReturnOneParam = (int a) -> {
                System.out.println(a);
                System.out.println(a);
            };
            noReturnOneParam.method(10);
            //多个参数无返回
            NoReturnMultiParam noReturnMultiParam = (int a,int b) -> {
                System.out.println(a);
                System.out.println(b);
            };
            noReturnMultiParam.method(10,20);
            //无参有返回
            ReturnNoParam returnNoParam = () -> {
                System.out.println("ok");
                return 110;
            };
            System.out.println(returnNoParam.method());
            //一个参数有返回
            ReturnOneParam returnOneParam = (int a) -> {
                return a+1000;
            };
            System.out.println(returnOneParam.method(10));
            //多个参数有返回
            ReturnMultiParam returnMultiParam = (int a,int b) -> {
                return a+b;
            };
            System.out.println(returnMultiParam.method(10,20));
        }
    }
    

    6.Lambda基本语法-简化

    package lambda;
    
    /**
     * @author 葡萄
     * 基础语法测试-简化
     */
    public class LambdaTest02 {
        public static void main(String[] args) {
            int num = 1000;
            //1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
            NoReturnMultiParam noReturnMultiParam = (a,b) -> {
                System.out.println(a+b);
            };
    
            //2.简化参数小括号,如果只有一个参数,则可以省略参数小括号
            NoReturnOneParam noReturnOneParam = a -> {
                System.out.println(a);
                System.out.println(a);
            };
            //3.简化方法体大括号,如果方法体只有一条语句,则可以省略方法体大括号
            NoReturnMultiParam noReturnMultiParam1 = (a,b) -> System.out.println(a+b);
            //4.如果方法体只有一条语句,并且是return语句,则可以省略方法体大括号
            ReturnMultiParam returnMultiParam = (a,b) -> a+b;
            ReturnMultiParam returnMultiParam1 = (a,b) -> num;
            ReturnMultiParam returnMultiParam3 = (a,b) -> num();
            ReturnMultiParam returnMultiParam2 = new ReturnMultiParam() {
                @Override
                public int method(int a, int b) {
                    return num();
                }
            };
        }
    
        public static int num(){
            return 10000;
        }
    }
    

    7.Lambda表达式常用示例

    7.1Lambda表达式引用方法

    有时候我们不是必须要自己重写匿名内部类的方法,我们可以利用lambda表达式的接口快速指向一个已经被实现的方法。

    • 语法:方法归属者::方法名 — 静态方法的归属者为类名,普通方法归属者为对象
    • 静态方法
      • 接口 对象名 = 类名::静态方法名;
    • 成员对象
      • 对象 对象名 = new 对象();
      • 接口 接口对象名 = 对象名::成员方法;
    • 要求:
      • 1.参数数量和类型要和接口中定义的一致
      • 2.返回值类型要与接口中定义的一致
    package lambda;
    
    /**
     * @author 葡萄
     * 基础语法测试-成员方法和静态方法的引用
     */
    public class LambdaTest03 {
        public static void main(String[] args) {
            //使用有一个参数,并带有返回值
            ReturnOneParam returnOneParam = a -> {
                return a+100;
            };
            System.out.println(returnOneParam.method(100));
            //使用有一个参数,并带有返回值
            ReturnOneParam returnOneParam2 = a -> num();
            System.out.println(returnOneParam2.method(100));
    
            //使用有一个参数,并带有返回值 调用的某个类的静态方法
            ReturnOneParam returnOneParam3 = LambdaTest03::numOne;
            System.out.println(returnOneParam3.method(100));
    
            //使用有一个参数,并带有返回值 调用的某个类的成员方法
            LambdaTest03 lambdaTest03 = new LambdaTest03();
            ReturnOneParam returnOneParam4 = lambdaTest03::two;
            System.out.println(returnOneParam4.method(100));
    
            System.out.println("-------------");
            //不能调用静态方法
    //        LambdaTest03 lambdaTest04 = new LambdaTest03();
    //        LambdaTest03.num();
    //        ReturnOneParam returnOneParam5 = lambdaTest04::numOne;
    //        System.out.println(returnOneParam4.method(100));
        }
    
        /**
         * 这是LambdaTest03里面的一个静态方法
         * @return
         */
        public static int num(){
            return 10000;
        }
    
        /**
         * 这是LambdaTest03里面的一个静态方法
         * @return
         */
        public static int numOne(int a){
            return a+10000;
        }
    
        /**
         * 这是LambdaTest03里面的一个成员方法
         * @return
         */
        public int two(int a){
            return a+100000;
        }
    
    }
    

    7.2构造方法的引用

    一般我们需要声明接口,该接口作为对象的生成器,通过 类名::new 的方式来实例化对象,然后调用方法返回对象。

    • 语法 ItemCreatorBlankConstruct construct2 = Item::new;
    package lambda;
    
    /**
     * @author 葡萄
     * 基础语法测试-构造方法的引用
     */
    public class LambdaTest04 {
        public static void main(String[] args) {
            //使用无参构造方法来引用
            ItemCreatorBlankConstruct construct = () -> new Item();
            Item item1 = construct.getItem();
            System.out.println(item1);
    
            ItemCreatorBlankConstruct construct2 =  Item::new;
            Item item2 = construct2.getItem();
            System.out.println(item2);
    
            //有参的构造方法
            ItemCreatorParamConstruct construct3 = Item::new;
            Item item3 = construct3.getItem(1,"葡萄",100);
            System.out.println(item3.name);
    
        }
    }
    
    public class Item {
        int id;
        String name;
        double price;
        public Item(int id,String name,double price){
            this.id = id;
            this.name = name;
            this.price = price;
        }
        public Item(){
    
        }
    }
    
    interface ItemCreatorBlankConstruct{
        Item getItem();
    }
    
    interface ItemCreatorParamConstruct{
        Item getItem(int id,String name,double price);
    }
    

    7.3Lambda表达式创建线程

    我们以往都是通过Thread对象,然后通过匿名内部类重写run()方法,一提到匿名内部类我们就应该想到可以使用lambda表达式来简化线程的创建过程。

    package lambda;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * @author 葡萄
     * 基础语法测试-创建线程对象
     */
    public class LambdaTest05 {
        public static void main(String[] args) {
            //Runnable
            new Thread(
                    new Runnable() {
                        @Override
                        public void run() {
                            System.out.println("ok");
                        }
                    }
            ).start();
    
            new Thread(()-> System.out.println("ok")).start();
    
            new Thread(()->{
                System.out.println("ok");
                System.out.println("ok");
            }).start();
    
    
            ExecutorService executorService = Executors.newCachedThreadPool();
            //Runnable
            executorService.submit(()->{
                System.out.println("我是runnable的接口实现");
            });
            //Callable
            executorService.submit(()->{
                return "完成";
            });
            executorService.submit(()->"完成");
        }
    }
    

    7.4Lambda遍历集合

    我们可以调用集合的public void forEach(Consumer<? super E> action)方法,通过lambda表达式的方式遍历集合中的元素。以下是Consumer接口的方法以及遍历集合的操作。Consumer接口是jdk为我们提供的一个函数式接口。

    @FunctionalInterface
    public interface Consumer<T> {
        void accept(T t);
        //...
    }
    
    • Lambda遍历简单集合
    package lambda;
    
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * @author 葡萄
     * 基础语法测试-遍历简单集合
     */
    public class LambdaTest06 {
        public static void main(String[] args) {
            List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
    //        List<Integer> integerList = new ArrayList<>();
    //        integerList.add(1);
    //        integerList.add(2);
    //        integerList.add(3);
    //        integerList.add(4);
    //        integerList.add(5);
    //        integerList.add(6);
            for (Integer integer : list) {
                System.out.print(integer+"\t");
            }
            System.out.println();
            System.out.println("------");
            for (int i = 0; i < list.size(); i++) {
                System.out.print(list.get(i)+"\t");
            }
            System.out.println();
            System.out.println("------");
            //lambda的遍历
            list.forEach((t)->{
                System.out.print(t+"\t");
            });
            System.out.println();
            System.out.println("------");
            list.forEach(t->{
                System.out.print(t+"\t");
            });
            System.out.println();
            System.out.println("------");
            list.forEach(t->System.out.print(t+"\t"));
            System.out.println();
            System.out.println("------");
            list.forEach(System.out::print);
    
        }
    }
    
    • Lambda遍历复杂集合
    package lambda;
    
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author 葡萄
     * 基础语法测试-遍历复杂集合
     */
    public class LambdaTest07 {
        public static void main(String[] args) {
            List<Item> itemList = new ArrayList<>();
            itemList.add(new Item(1,"饺子",10.00));
            itemList.add(new Item(2,"汤圆",5.22));
            itemList.add(new Item(3,"奶茶",20.56));
            itemList.add(new Item(4,"布丁",22.33));
            itemList.add(new Item(5,"芋圆",16.05));
    
            //以前的遍历方法
            for (int i = 0; i < itemList.size(); i++) {
                System.out.println(itemList.get(i)+"\t");
            }
            for (Item item : itemList) {
                System.out.println(item);
            }
    
            System.out.println("---------");
    
            //使用lambda表达式遍历
            itemList.forEach(item -> System.out.println(item));
            System.out.println("---------");
            itemList.forEach(item -> System.out.println(item.getName()));
            System.out.println("---------");
            itemList.forEach(System.out::println);
    
        }
    }
    

    其中的Item类如下

    package lambda;
    
    public class Item {
        int id;
        String name;
        double price;
        public Item(int id,String name,double price){
            this.id = id;
            this.name = name;
            this.price = price;
        }
        public Item(){
    
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public double getPrice() {
            return price;
        }
    
        public void setPrice(double price) {
            this.price = price;
        }
    
        @Override
        public String toString() {
            return "Item{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", price=" + price +
                    '}';
        }
    }
    
    

    7.5删除集合中的某个元素

    我们通过public boolean removeIf(Predicate<? super E> filter)方法来删除集合中的某个元素,Predicate也是jdk为我们提供的一个函数式接口,可以简化程序的编写。

    package lambda;
    
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author 葡萄
     * 基础语法测试-集合元素删除
     */
    public class LambdaTest08 {
        public static void main(String[] args) {
            List<Item> itemList = new ArrayList<>();
            itemList.add(new Item(1,"饺子",10.00));
            itemList.add(new Item(2,"汤圆",5.22));
            itemList.add(new Item(3,"奶茶",20.56));
            itemList.add(new Item(4,"布丁",22.33));
            itemList.add(new Item(5,"芋圆",16.05));
    
            itemList.forEach(System.out::println);
            System.out.println("---------");
    
            //删除id=2的元素
            for (Item item : itemList) {
                if (item.getId()==2){
                    itemList.remove(item);
                    break;
                }
            }
    
            itemList.forEach(System.out::println);
            System.out.println("---------");
    
            //使用lambda移除id=5
            itemList.removeIf(item -> item.getId()==5);
            itemList.forEach(System.out::println);
            System.out.println("---------");
        }
    }
    

    7.6集合内元素的排序

    在以前我们若要为集合内的元素排序,就必须调用sort方法。传入比较器匿名内部类重写compare方法,我们现在可以使用lambda表达式来简化代码。

    package lambda;
    
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    
    /**
     * @author 葡萄
     * 基础语法测试-集合元素排序
     */
    public class LambdaTest09 {
        public static void main(String[] args) {
            List<Item> itemList = new ArrayList<>();
            itemList.add(new Item(1,"饺子",10.00));
            itemList.add(new Item(2,"汤圆",5.22));
            itemList.add(new Item(3,"奶茶",20.56));
            itemList.add(new Item(4,"布丁",22.33));
            itemList.add(new Item(5,"芋圆",16.05));
    
            itemList.forEach(System.out::println);
            System.out.println("---------");
    
    //        Collections.sort(itemList, new Comparator<Item>() {
    //            @Override
    //            public int compare(Item o1, Item o2) {
    //                return (int) (o1.getPrice()- o2.getPrice());
    //            }
    //        });
    //        Collections.sort(itemList,(o1,o2)->{
    //            return (int) (o1.getPrice()- o2.getPrice());
    //        });
            Collections.sort(itemList, (o1,o2)->(int) (o1.getPrice()- o2.getPrice()));
            itemList.forEach(System.out::println);
            System.out.println("---------");
    
        }
    }
    
    展开全文
  • lambda表达式

    2021-04-09 19:48:44
    Lambda表达式学习笔记 1.为什么使用Lambda? Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使...

    Lambda表达式学习笔记

    1.为什么使用Lambda?

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

    2.Lambda表达式使用举例

    package com.deng;
    
    import org.junit.Test;
    
    import java.util.Comparator;
    
    /**
     * Lambda表达式使用举例
     * @author Deng Huawei
     * @create 2021-04-09 12:36
     */
    public class TestLambda {
    
        @Test
        public void test1(){
            Runnable r1 = new Runnable() {
                @Override
                public void run() {
                    System.out.println("This is a test!");
                }
            };
            r1.run();
            System.out.println("--------------------下面是Lambda表达式---------------------");
            Runnable r2 = () -> System.out.println("This is a Lambda test!");
            r2.run();
        }
    
        @Test
        public void test2(){
            Comparator<Integer> cmp1 = new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return Integer.compare(o1,o2);
                }
            };
            int compare1 = cmp1.compare(12,10);
            System.out.println(compare1);
            System.out.println("--------------------------Lambda-------------------");
            Comparator<Integer> cmp2 = (o1,o2) -> Integer.compare(o1,o2);
            int compare2 = cmp2.compare(21,32);
            System.out.println(compare2);
            System.out.println("--------------------------方法引用-------------------");
            Comparator<Integer> cmp3 = Integer::compare;
            int compare3 = cmp3.compare(21,32);
            System.out.println(compare3);
        }
    }
    

    3.Lambda表达式语法使用

    3.1.举例

    (o1,o2) -> Integer.compare(o1,o2);
    

    3.2.格式

    • -> :lambda操作符,或箭头操作符
    • ->左边:lambda形参列表(其实就是接口中的抽象方法形参列表)
    • ->右边:lambda体 (其实就是重写的方法的方法体)

    3.3.Lambda表达式的使用(6种情况)

    • 语法格式1:无参,无返回值(上面的Runnable方法!!)

      @Test
      public void test1(){
          Runnable r1 = () -> {System.out.println("This is a test!");}
          r1.run();
      }
      
    • 语法格式2:Lambda需要一个参数,但是没有返回值

        @Test
        public void test2(){
            Consumer<String> con1 = new Consumer<String>() {
                @Override
                public void accept(String s) {
                    System.out.println(s);
                }
            };
            con1.accept("普通方法!");
            System.out.println("**************************");
            Consumer<String> con2 = (String s) -> {
                System.out.println(s);
            };
            con2.accept("lambda表示方法!");
        } 
    
    • 语法格式3: 数据类型可以省略,因为可由编译器推断得出,称为“类型推断“
       //语法格式3:数据类型可以省略,因为可由编译器推断得出,称为“类型推断“
        @Test
        public void test3(){
            Consumer<String> con2 = (String s) -> {
                System.out.println(s);
            };
            con2.accept("lambda表示方法!");
            System.out.println("*************************优化!!");
            Consumer<String> con3 = (s) -> {
                System.out.println(s);
            };
            con2.accept("lambda表示优化方法!类型推断!!!");
        }
    

    类型推断:

     ArrayList<String> arrayList = new ArrayList<>();   //类型推断
            int[] arr = new int[]{12,2,3,};    //可改为
            int[] arr1 = {1,2,3};               //类型推断
    
    • 语法格式4:Lambda 若只需要一个参数时,参数的小括号可以省略

      //语法格式4:Lambda 若只需要一个参数时,参数的小括号可以省略
      @Test
      public void test4(){
          Consumer<String> con3 = (s) -> {
              System.out.println(s);
          };
          con3.accept("lambda表示优化方法!类型推断!!!");
          System.out.println("***************************");
          Consumer<String> con4 = s-> {
              System.out.println(s);
          };
          con4.accept("lambda表示优化方法,类型推断!!!去掉小括号");
      }
      
    • 语法格式5:Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值

      //语法格式5:Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值
      @Test
      public void test5(){
          Comparator<String> com1 = new Comparator<String>() {
              @Override
              public int compare(String o1, String o2) {
                  System.out.println(o1);
                  System.out.println(o2);
                  return o1.compareTo(o2);
              }
          };
          System.out.println(com1.compare("12", "21"));
          System.out.println("原始写法****************************");
      
          Comparator<String> com2 = (o1,o2) ->{
              System.out.println(o1);
              System.out.println(o2);
              return o1.compareTo(o2);
          };
          System.out.println(com1.compare("12", "6"));
      }
      
    • 语法格式6:当:Lambda体只有一条语句时,return与大括号若有,都可以省略

      //语法格式6:当:Lambda体只有一条语句时,return与大括号若有,都可以省略
      @Test
      public void test6(){
          Comparator<Integer> com1 = (o1,o2) ->{
              return o1.compareTo(o2);
          };
          System.out.println(com1.compare(12,6));
          System.out.println("*******************************");
          Comparator<Integer> com2 = (o1,o2) -> o1.compareTo(o2);  //System.out.println();
          System.out.println(com2.compare(60,63));
      }
      

    3.4.Lambda表达式本质

    作为接口的实例(具体实现类)

    4.总结

    • ->左边:lambda形参列表的参数类型可以省略(类型推断);如果参数列表只有一个参数,其一对()也可以省略

    • ->右边:lambda体应该使用一对{}进行包裹,如果lambda体只有一条执行语句(可能是return语句),可以省略一对{}以及这个return关键字(注意:省了{}一定要去掉return);

    重点!!!!需要 接口只有一个抽象方法,依赖于函数式接口!!!!!!!!!!!!!!

    5.练习

    将Employee按照年龄进行排序,如果年龄相同,则按照姓名进行排序。提示:Collections.sort()

    public class test {
        List<employee> list = Arrays.asList(
                new employee(1,"张三",18,2000),
                new employee(2,"李四",25,2011),
                new employee(3,"王五",20,3000),
                new employee(4,"孙武路",23,3000),
                new employee(5,"张无忌",30,5000)
        );
    
        @Test
        public void test(){
            Collections.sort(list, (e1,e2) -> {
                if(e1.getAge() == e2.getAge()){
                    return e1.getName().compareTo(e2.getName());
                }else {
                    return Integer.compare(e1.getAge(),e2.getAge());
                }
            });
            for (employee emp : list) {
                System.out.println(emp);
            }
        }
    }
    
    展开全文
  • Lambda表达式详解

    2020-11-16 18:02:15
    Lambda表达式详解Lambda表达式简介对接口的要求@FunctionalInterfaceLambda基础语法Lambda语法简化Lambda表达式常用示例Lambda表达式引用方法构造方法的引用Lambda表达式创建线程遍历集合删除集合中的某个元素集合内...
  • Lambda表达式概述1.1 什么是Lambda表达式1.2 Lambda表达式的标准格式2. Lambda表达式小练习2.1 无参数无返回值练习2.2 有参数无返回值练习2.3 有参数有返回值练习3. Lambda表达式的简化格式与使用前提3.1 Lambda...
  • C++ lambda表达式入门

    万次阅读 多人点赞 2018-11-04 12:17:01
    1.lambda表达式 lambda表达式 是一个函数,一个匿名函数,也就是没有函数名的函数,为什么不需要函数名呢,因为我们直接(一次性的)用它,嵌入式用的它,不需要其他地方用它。 也叫闭包,闭就是封闭的意思,就是...
  • lambda表达式总结

    2020-06-08 13:38:16
    lambda表达式总结 表达式形式 lambda 参数 : 表达式 例: f = lambda x,y : x + y # 创建一个lambda表达式 print (f(1, 2)) # 调用表达式 lambda表达式,有被称为匿名函数,在定义lambda表达式时要注意, 假设...
  • lambda表达式优化代码

    2019-04-27 20:28:02
    接下来的是用lambda表达式优化后的代码: import java.util.Arrays; public class Demo07ComparatorLambda { public static void main(String[] args) { Person[] array = { new Person("古力娜扎", 19), ...
  • Java使用Lambda表达式优化斗地主案例 思路:使用Lambda作为比较方法的参数和返回值。 ```java import java.util.*; public class MMain { public static void main(String[] args) { //准备牌 ArrayList<...
  • Lambda表达式入门

    2020-08-06 09:25:50
    Lambda表达式入门 学会lambda,简化代码编写,让代码更加优美 Lambda 简介 Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极...
  • 基于C++ Lambda表达式的程序优化 2012-06-21 11:59 这是一个关于C\C++程序员的一个小故事,关于C++11――刚刚通过的新标准的一个小故事… 请不要误会,题目中所提及的“优化”并不是提升程序的性能―...
  • lambda表达式及闭包

    2020-10-15 14:06:44
    lambda表达式及闭包Lambda简介对接口的要求Lambda 基础语法Lambda 语法简化Lambda 表达式常用示例Lambda 表达式中的闭包问题什么是闭包 Lambda简介 Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,836
精华内容 4,734
关键字:

lambda表达式排序优化