精华内容
下载资源
问答
  • lamda表达式

    2020-10-03 04:29:15
    lamda表达式1.Lamda标准格式3.lamda表达式有参数有返回值 1.Lamda标准格式 3.lamda表达式有参数有返回值


    1.Lamda标准格式

    在这里插入图片描述

    2.lamda表达式无参数无返回值

    在这里插入图片描述

    3.lamda表达式有参数有返回值

    在这里插入图片描述

    展开全文
  • Lamda表达式

    2019-11-28 22:09:28
    Lamda表达式 一、Lamda表达式 1.为什么要使用Lamda表达式 A.避免匿名内部类定义过多; B.可以让你的代码看起来很简洁; C.去掉了一堆没有意义的代码,只留下核心的逻辑。 2.Lamda表达式的书写格式 new Thread(()-&...

    Lamda表达式

    一、Lamda表达式

    1.为什么要使用Lamda表达式

    A.避免匿名内部类定义过多;

    B.可以让你的代码看起来很简洁;

    C.去掉了一堆没有意义的代码,只留下核心的逻辑。

    2.Lamda表达式的书写格式

    new Thread(()->System.out.println(“Lamda表达式”)).start()

    3.Lamda表达式的关键

    理解Functional Interface(函数式接口)

    二、函数式接口的定义

    1.任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口
    public interface Runnable {
    	public abstract void run();
    }
    //一个接口只有一个方法,超过一个抽象方法的接口都不能称为函数式接口!!!
    
    2.对于函数式接口,我们可以通过lambda表达式来创建该接口的对象

    三、演示

    通过代码来推导Lamda表达式,请读者根据我的推导步骤一步一步的实现。

    步骤1:

    public class TestLambda {
        public static void main(String[] args) {
            //实例化一个对象,调用方法
            Lambda1 lambda1 = new Lambda1();
            lambda1.lambdaMethod();
        }
    }
    
    //定义一个函数式接口:一个接口有且仅有一个方法;
    interface LambdaInterface {
        void lambdaMethod();
    }
    
    //实现类
    class Lambda1 implements LambdaInterface {
    
        @Override
        public void lambdaMethod() {
            System.out.println("Lambda1");
        }
    }
    

    步骤2:

    public class TestLambda {
    
        //静态内部类
        static class Lambda1 implements LambdaInterface {
    
            @Override
            public void lambdaMethod() {
                System.out.println("Lambda1");
            }
        }
    
        public static void main(String[] args) {
            //实例化一个对象,调用方法
            Lambda1 lambda1 = new Lambda1();
            lambda1.lambdaMethod();
        }
    }
    
    //定义一个函数式接口:一个接口有且仅有一个方法;
    interface LambdaInterface {
        void lambdaMethod();
    }
    

    步骤3:

    public class TestLambda {
        
        public static void main(String[] args) {
    
            //局部内部类,注意要把它放在实例化之前
            class Lambda1 implements LambdaInterface {
    
                @Override
                public void lambdaMethod() {
                    System.out.println("Lambda1");
                }
            }
    
            //实例化一个对象,调用方法
            Lambda1 lambda1 = new Lambda1();
            lambda1.lambdaMethod();
        }
    }
    
    //定义一个函数式接口:一个接口有且仅有一个方法;
    interface LambdaInterface {
        void lambdaMethod();
    }
    

    步骤4:

    public class TestLambda {
    
        public static void main(String[] args) {
    
            //匿名内部类:没有类的名称,必须借助接口或父类;
            LambdaInterface testLambda = new LambdaInterface() {
                @Override
                public void lambdaMethod() {
                    System.out.println("Lambda1");
                }
            };
            testLambda.lambdaMethod();
        }
    }
    
    //定义一个函数式接口:一个接口有且仅有一个方法;
    interface LambdaInterface {
        void lambdaMethod();
    }
    

    步骤5:

    public class TestLambda {
    
        public static void main(String[] args) {
    
            //匿名内部类:没有类的名称,必须借助接口或父类;
            LambdaInterface testLambda = new LambdaInterface() {
                @Override
                public void lambdaMethod() {
                    System.out.println("Lambda1");
                }
            };
            testLambda.lambdaMethod();
    
            //用Lambda简化
            testLambda = () -> {
                System.out.println("Lambda2");
            };
            testLambda.lambdaMethod();
        }
    }
    
    //定义一个函数式接口:一个接口有且仅有一个方法;
    interface LambdaInterface {
        void lambdaMethod();
    }
    

    推导过程示意图:
    在这里插入图片描述
    再进行一次含有参数的Lambda表达式推导,说明一些问题:

    public class TestLambda2 {
        public static void main(String[] args) {
            Lambda2 lambda2 = new Lambda2();
            lambda2.value(88);
        }
    }
    
    interface LambdaInterface2 {
        int value(int b);
    }
    
    //实现类
    class Lambda2 implements LambdaInterface2 {
    
        @Override
        public int value(int b) {
            System.out.println("数值 = " + b);
            return b;
        }
    }
    
    public class TestLambda2 {
        public static void main(String[] args) {
            Lambda2 lambda2 = new Lambda2();
            lambda2.value(88);
        }
    
        //静态内部类
        static class Lambda2 implements LambdaInterface2 {
    
            @Override
            public void value(int b) {
                System.out.println("数值 = " + b);
            }
        }
    }
    
    interface LambdaInterface2 {
        void value(int b);
    }
    
    public class TestLambda2 {
        public static void main(String[] args) {
    
            //局部内部类
            class Lambda2 implements LambdaInterface2 {
    
                @Override
                public void value(int b) {
                    System.out.println("数值 = " + b);
                }
            }
            Lambda2 lambda2 = new Lambda2();
            lambda2.value(88);
        }
    }
    
    interface LambdaInterface2 {
        void value(int b);
    }
    
    public class TestLambda2 {
        public static void main(String[] args) {
    
            //匿名内部类
            LambdaInterface2 lambdaInterface2 = new LambdaInterface2() {
                @Override
                public void value(int b) {
                    System.out.println("数值 = " + b);
                }
            };
            lambdaInterface2.value(88);
        }
    }
    
    interface LambdaInterface2 {
        void value(int b);
    }
    

    在这里插入图片描述
    看上图,蓝色阴影部分的代码,Lambda表达式的形式就是将这部分里的括号()与花括号{}之间添加一个箭头即可。

    public class TestLambda2 {
        public static void main(String[] args) {
            LambdaInterface2 lambdaInterface2 = null;
            //Lambda简化1:
            lambdaInterface2 = (int b) -> {
                System.out.println("简化1--->数值 = " + b);
            };
            lambdaInterface2.value(88);
    
            //Lambda简化2:简化参数类型
            //当有多个参数时,他们的参数类型要去掉就都去掉,要不然就都不去掉!!!
            lambdaInterface2 = (b) -> {
                System.out.println("简化2--->数值 = " + b);
            };
            lambdaInterface2.value(100);
    
            //Lambda简化3:简化括号
            //当有多个参数时,括号不可以被去掉!!!
            lambdaInterface2 = b -> {
                System.out.println("简化3--->数值 = " + b);
            };
            lambdaInterface2.value(99);
    
            //Lambda简化4:简化花括号
            //当方法体{}中只有一条执行语句(即:只有一个分号)时,才可以这样简化!!!
            //若方法体{}中有多条语句,必须用花括号{}包裹着;
            lambdaInterface2 = (b) -> System.out.println("简化4--->数值 = " + b);
            lambdaInterface2.value(77);
        }
    }
    
    interface LambdaInterface2 {
        void value(int b);
    }
    
    //多个参数,多条语句的情况
    public class TestLambda2 {
        public static void main(String[] args) {
    
            //匿名内部类
            LambdaInterface2 lambdaInterface2 = new LambdaInterface2() {
                @Override
                public void value(int a, int b) {
                    System.out.println("数值a = " + a);
                    System.out.println("数值b = " + b);
                }
            };
        }
    }
    
    interface LambdaInterface2 {
        void value(int a, int b);
    }
    

    四、总结

    1.Lambda表达式的前提是接口为函数式接口(一个接口有且仅有一个方法);
    2.多个参数也可以去掉参数类型,要去掉就都去掉,要保留就都保留,但是必须加上括号;
    3.Lambda表达式只有在方法体{}中含有一条语句的情况下,才可以去掉花括号;若含有多条语句,不可去掉花括号{}。
    展开全文
  • lamda 表达式

    2016-06-30 16:35:00
    高阶语言中的lamda表达式, 灵感来自于lamda演算。lamda演算包括一条变换规则 (变量替换) 和一条函数定义方式, 通过带入和替换, 对输入产生输出。 Connect 新用法 connect 连接 信号槽 connect(sender,...

    Lamda 表达式

    高阶语言中的lamda表达式, 灵感来自于lamda演算。lamda演算包括一条变换规则 (变量替换) 和一条函数定义方式, 通过带入和替换, 对输入产生输出。


    Connect 新用法

    connect 连接 信号槽

    connect(sender, &Sender::valueChanged, receiver, &Receiver::updateValue );

    connect 连接普通函数 someFunctionSomeFunction 应该是一个语法正确的函数, 可以是 static 函数, 也可以是同一个类的成员函数。

    connect(sender, &Sender::valueChanged, someFunction);

    命名 connect 以及 why 命名 connect

    QMetaObject::Connection m_connection;
    //…
    m_connection = QObject::connect(…);
    //…
    Qobject::disconnect(m_connection);

    lamda 表达式

    void doYourStuff(const QByteArray &page)
    {
    QTcpSocket *socket = new QTcpSocket;
    socket->connectToHost("qt.io", 80);
    QObject::connect(socket, &QTcpSocket::connected, [socket, page] () {
    socket->write(QByteArray("GET " + page + ""));
    });
    QObject::connect(socket, &QTcpSocket::readyRead, [socket] () {
    qDebug()<< "GOT DATA "<< socket->readAll();
    });
    QObject::connect(socket, &QTcpSocket::disconnected, [socket] () {
    qDebug()<< "DISCONNECTED ";
    socket->deleteLater();
    });
     
    QObject::connect(socket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>
    (&QAbstractSocket::error), [socket](QAbstractSocket::SocketError) {
    qDebug()<< "ERROR " << socket->errorString();
    socket->deleteLater();
    });
    }



    C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。





    Lambda的语法形式如下:

    1. Capture 子句(在 C++ 规范中也称为 lambda 引导。)

    2. 参数列表(可选)。 lambda 声明符)

    3. 可变规范(可选)。

    4. 异常规范(可选)。

    5. 尾随返回类型(可选)。

    6. lambda 体”

    Capture 子句

    Lambda 可在其主体中引入新的变量(用 C++14,它还可以访问(或“捕获”)周边范围内的变量。 lambdacapture 子句开头,它指定要捕获的变量以及是通过值还是引用进行捕获。 &) 前缀的变量通过引用访问,没有该前缀的变量通过值访问。

    [ ] 指示 lambda 表达式的主体不访问封闭范围中的变量。

    可以使用默认捕获模式(capture-default)来指示如何捕获 lambda 中引用的任何外部变量:[&] 表示通过引用捕获引用的所有变量,而 [=] 表示通过值捕获它们。 可以使用默认捕获模式,然后为特定变量显式指定相反的模式。例如,如果 lambda 体通过引用访问外部变量 total 并通过值访问外部变量 factor,则以下 capture 子句等效:

    [&total, factor]
    [factor, &total]
    [&, factor]
    [factor, &]
    [=, &total]
    [&total, =]


    Capture
    子句的可能取值:
    1
    、空。没有使用任何函数对象参数。
    2
    =。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。
    3
    &。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。
    4
    this。函数体内可以使用Lambda所在类中的成员变量。
    5
    a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。
    6
    &a。将a按引用进行传递。
    7
    a, &b。将a按值进行传递,b按引用进行传递。
    8
    =&a, &b。除ab按引用进行传递外,其他参数都按值进行传递。
    9
    &, a, b。除ab按值进行传递外,其他参数都按引用进行传递。


    参数列表

    lambda 表达式可以将另一个 lambda 表达式作为其参数

    C++14 中,如果参数类型是泛型,则可以使用 auto 关键字作为类型说明符。



         
    三、mutableexception声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意 是能修改拷贝,而不是值本身)。exception声明用于指定函数抛出的异常,如抛出整数类型的异常,可以使用throw(int)
         
    四、->返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。
         
    五、{函数体},标识函数的实现,这部分不能省略,但函数体可以为空。
         
    下面给出了一段示例代码,用于演示上述提到的各种情况,代码中有简单的注释可作为参考。

    class CTest
    {
    public:
     CTest() : m_nData(20) { NULL; }
     void TestLambda()
     {
      vector<int> vctTemp;
      vctTemp.push_back(1);
      vctTemp.push_back(2);

      // 
    无函数对象参数,输出:1 2
      {
       for_each(vctTemp.begin(), vctTemp.end(), [](int v){ cout << v << endl; });
      }

      // 
    以值方式传递作用域内所有可见的局部变量(包括this),输出:11 12
      {
       int a = 10;
       for_each(vctTemp.begin(), vctTemp.end(), [=](int v){ cout << v+a << endl; });
      }

      // 
    以引用方式传递作用域内所有可见的局部变量(包括this),输出:11 13 12
      {
       int a = 10;
       for_each(vctTemp.begin(), vctTemp.end(), [&](int v)mutable{ cout << v+a << endl; a++; });
       cout << a << endl;
      }

      // 
    以值方式传递局部变量a,输出:11 13 10
      {
       int a = 10;
       for_each(vctTemp.begin(), vctTemp.end(), [a](int v)mutable{ cout << v+a << endl; a++; });
       cout << a << endl;
      }

      // 
    以引用方式传递局部变量a,输出:11 13 12
      {
       int a = 10;
       for_each(vctTemp.begin(), vctTemp.end(), [&a](int v){ cout << v+a << endl; a++; });
       cout << a << endl;
      }

      // 
    传递this,输出:21 22
      {
       for_each(vctTemp.begin(), vctTemp.end(), [this](int v){ cout << v+m_nData << endl; });
      }

      // 
    b按引用传递外,其他均按值传递,输出:11 12 17
      {
       int a = 10;
       int b = 15;
       for_each(vctTemp.begin(), vctTemp.end(), [=, &b](int v){ cout << v+a << endl; b++; });
       cout << b << endl;
      }


      // 
    操作符重载函数参数按引用传递,输出:2 3
      {
       for_each(vctTemp.begin(), vctTemp.end(), [](int &v){ v++; });
       for_each(vctTemp.begin(), vctTemp.end(), [](int v){ cout << v << endl; });
      }

      // 
    空的Lambda表达式
      {
       [](){}();
       []{}();
      }
     }

    private:
     int m_nData;
    };


    转载于:https://www.cnblogs.com/aslistener/p/5630456.html

    展开全文
  • 1、什么是Lamda表达式 Lamda表达式是一个函数,其通用写法为: [capture](parameters) mutable ->return-type{statement} 其中: capture:捕捉列表-...

    1、什么是Lamda表达式

                    Lamda表达式是一个函数,其通用写法为:

                                  [capture](parameters) mutable ->return-type{statement}       

                    其中:

                    capture:捕捉列表------可以在表达式中使用代码前后的变量

                    parameters:给这个lamda表达式传递的参数列表,如果不需要传参的话,parameters可以连同()一起省略。

                    mutable:mutable修饰符。默认情况下,Lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空);

                    ->return-type:返回类型。用追踪返回类型形式声明函数的返回类型。我们可以在不需要返回值的时候也可以连同符号”->”一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导;

                    {statement}:函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。

     

    eg: 

              int     a = 1;

             int      b = 2;

             auto  func = [=,&b](int  c)->int{return  b +=a+c;};

    解释:

                 b为从外部捕获的变量

                c为传递给lamda表达式的参数

                返回值数据类型为int

               lamda函数表达式函数体为:b+=a+c

    2、QT的槽函数中使用lamda表达式

            connect(信号产生者,所捕获的信号,lamda表达式);

    信号产生者:this指针

    捕捉信号:finish

    [&] 捕捉列表:finish信号所传递的参数

    展开全文
  • 这里介绍过一些lamda表达式的基本用法。 这一篇谈一下自己对lamda表达式的一些感悟。 1.困惑 不知道大家有没有这种感觉,看源码尤其是一些框架代码,只要是有lamda表达式或者匿名内部类的地方,就容易头晕,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,940
精华内容 776
关键字:

lamda表达式