-
lamada表达式
2020-03-16 16:26:50title: lamada表达式 date: 2018-12-16 15:54:20 updated: 2020-03-06 23:43:58 categories: java tags: - java 此文档为java中lamada表达式的学习总结 java中的lamada表达式 x -> 2 * x 接收一个参数(数字类型...
title: lamada表达式
date: 2018-12-16 15:54:20
updated: 2020-03-06 23:43:58
categories: java
tags:
- java
此文档为java中lamada表达式的学习总结
java中的lamada表达式
x -> 2 * x 接收一个参数(数字类型),返回其2倍的值
() -> {} 没有参数,右边的函数里面什么也不做
lamada实现Runnable接口:
Thread thread = new Thread( () -> {System.out.print("hello")} ); 等同于 Thread thread = new Thread( new Runnable(){ public void run(){ System.out.print("hello"); } } );
-
Lamada表达式
2018-10-23 16:51:45而Lamada表达式提供了一个类似匿名函数的特性,即在需要一个函数,而又不想费力去命名一个函数的情况下使用 形式: [捕获列表(函数对象参数)](参数列表) mutable或exception声明(可选) -> 返回类型{ //...Lamada
以往C++需要传入一个函数的时候,必须事先进行声明,视情况可以声明为一个普通函数然后传入函数指针,或者声明一个函数对象,然后传入一个对象。而Lamada表达式提供了一个类似匿名函数的特性,即在需要一个函数,而又不想费力去命名一个函数的情况下使用
形式:
[捕获列表(函数对象参数)](参数列表) mutable或exception声明(可选) -> 返回类型{ //函数体 }
- 函数对象参数是传递给编译器自动生成的函数对象类的构造函数的,不能省略;函数对象参数只能使用那些到定义Lamada为止时Lamada所在范围内可见的局部变量(包括Lamada所在类的this)
值捕获
与参数传值类似,值捕获的前期是变量可以拷贝,不同之处则在于,被捕获的变量在 lambda 表达式被创建时拷贝,而非调用时才拷贝void learn_lambda_func_1() { int value_1 = 1; auto copy_value_1 = [=] { return value_1; }; value_1 = 100; auto stored_value_1 = copy_value_1(); // 这时, stored_value_1 == 1, 而 value_1 == 100. // 因为 copy_value_1 在创建时就保存了一份 value_1 的拷贝 }
引用捕获
与引用传参类似,引用捕获保存的是引用,值会发生变化。void learn_lambda_func_2() { int value_2 = 1; auto copy_value_2 = [&] { return value_2; }; value_2 = 100; auto stored_value_2 = copy_value_2(); // 这时, stored_value_2 == 100, value_1 == 100. // 因为 copy_value_2 保存的是引用 }
-
Lamada 表达式
2020-08-27 22:05:40什么是Lamada表达式 基本含义: Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数...什么是Lamada表达式
基本含义:
Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。
Java中:
lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。
为什么引入Lamada表达式
引入Lamada表达式前,在Java中传递一个代码段并不容易,不能直接传递代码段。Java 是一种面向对象语言,所以必须构造一个对象, 这个对象的类需要有一个方法能包含所需的代码。
Lamada语法
1.参数,箭头(→)以及一个表达式。
(String first, String second)-> first.length()-second.length()
(String first, String second)-> { if (first.length()<second.length()) return -1; else if (first.length()>second.length()) return 1; else return 0; }
()-> { for(int i=100; i>=0; i--) System.out.printIn(i); }
Comparator<String> comp=(first,second) // Same as (String first, String second) -> first.1ength()-second.length();
ActionListener listener = event -> System.out.print1n("The time is " + new Date());
(int x)->{ if(x>= 0) return 1; }
Lamada应用实例
-
lamada 表达式
2011-04-23 10:39:00使用linq to object来处理数据的时,经常会出现一个语句包含几个委托的情况,C sharp3 的lambda表达 式在不牺牲可读性的前提下使这一切成为可能, 简而言之:: lamada 表达式 是对llinq的基本功能是创建操作管道,以及这些操作需要的任何状态,这些操作表示了各种关于数据的
逻辑,如何刷选,如何排序以及如何将不同的数据源联接到一起,当linq查询在"进程内"执行的时候
那些操作通常用委托来表示:使用linq to object来处理数据的时,经常会出现一个语句包含几个委托的情况,C sharp3 的lambda表达
式在不牺牲可读性的前提下使这一切成为可能,
简而言之:: lamada 表达式 是对linq数据管线中的操作进行表示的一种符合语言习惯的方式:
1:作为委托的lambda表达式:
从许多方面: lamada 表达式都可以看作事实C sharp2的匿名方法的一种演变 ,匿名方法能做的几乎
一切事情都可以用lamada 表达式来完成:特别是: 捕获的变量在lambda表达式的行为和匿名方法是一样的,从显示的形式来看,两者并不大的区别,
只是lamada 表达式支持许多快捷语法,使它们更易读,更简练:
与匿名方法相似.lamada 表达式有特殊的转换规则,表达式类型的本身并非委托类型,
但它可以通过多种方式隐式或显式地转换一个委托实例:匿名函数这个术语同时涵盖了匿名方法和lambda表达式---在很多情况下,两者可以使用相同的转换规则:
Func<string, int> returnLength;
returnLength = delegate(string text) { return text.Length; };Console.WriteLine(returnLength("Hello"));
匿名方法是: delegate(string text) { return text.Length; };
也是打算转换成lamabda表达式的部分:lamada 表达式最冗长的形式是:
(显式类型参数列表) => {语句}; // => 这个东东用来告诉编译器: 我们正在使用一个lambda表达式
Func<string, int> returnLength;
returnLength = (string text) => { return text.Length; };
大多数的时候: 可以用一个表达式来表示整个主体,该表达式的值是lamabda的结果:
格式即将变成:
(显式类型的参数列表 => 表达式 )
(string text=>text.length隐式类型的参数列表
(隐式类型的参数列表) =>表达式:
隐式类型的参数列表就是一个以逗号分隔的名称列表,没有类型,但显式类型和隐式类型的
参数不能混合使用----要么整个列表都是显式类型的,要么全部是隐式类型.除此之外如果有
任何out参数或 ref参数,就只能使用显式类型:
可以继续写成:
(text)=>text.length:单一参数的快捷语法:
如果 lamada 表达式只需一个参数,而且哪个参数可以隐式(指定)类型,C sharp3就允许省略圆括号:这种格式的 lamada 表达式是:
参数名 => 表达式
text=>text.length:
//*****: 使用list<t>事件简单的例子:
对列表进行刷选,排序并设置其他操作:< list><t>的findall的方法,它获取一个predicate<T>,并返回一个新列表,新列表中包含原始列表中与
谓语匹配的所有的元素:
sort方法获取一个comparision<T>,并相应地对列表进行排序,最后一个获取:foreach方法获取一个Action<T>
,对每个元素执行设置的行为:class FilmFilteringAndSorting
{
class Film
{
public string Name { get; set; }
public int Year { get; set; }
}
static void Main()
{
var films = new List<Film>
{
new Film {Name="Jaws", Year=1975},
new Film {Name="Singing in the Rain", Year=1952},
new Film {Name="Some like it Hot", Year=1959},
new Film {Name="The Wizard of Oz", Year=1939},
new Film {Name="It's a Wonderful Life", Year=1946},
new Film {Name="American Beauty", Year=1999},
new Film {Name="High Fidelity", Year=2000},
new Film {Name="The Usual Suspects", Year=1995}
};
#region--Action行为// < list><t>的findall的方法,它获取一个predicate<T>,并返回一个新列表,新列表中包含原始列表中与
//谓语匹配的所有的元素:
// sort方法获取一个comparision<T>,并相应地对列表进行排序,最后一个获取:foreach方法获取一个Action<T>
// ,对每个元素执行设置的行为:
//lamabda表达式
//Action<Film> print =
// film => Console.WriteLine("Name={0}, Year={1}", film.Name, film.Year);//用委托表达式
Action<Film> print = delegate(Film film) //表示方法: Action<T>对T的某个实例做某事
{
Console.WriteLine("Name={0}, Year={1}", film.Name, film.Year);
};//Action<Film> print =
// film => Console.WriteLine("Name={0}, Year={1}", film.Name, film.Year);
//Note: extra lines added for clarity when running
Console.WriteLine("All films");
films.ForEach(print);
Console.WriteLine();
#endregion
Console.WriteLine("Oldies");
films.FindAll(film => film.Year < 1960)
.ForEach(print);
Console.WriteLine();
//用C#2.0委托表达式
Predicate<Film> filter = delegate(Film film) //查找符合的条件
{
return film.Year < 1960;
};
Console.WriteLine("OldiesC#2.0的委托表达方式");
films.FindAll(filter).ForEach(print);
Console.WriteLine();
Console.WriteLine("Sorted");
films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name));
films.ForEach(print);Console.WriteLine("SortedC#2.0的委托表达方式");
Comparison<Film> compare = delegate(Film f1, Film f2)
{
return f1.Name.CompareTo(f2.Name);
};
films.Sort(compare);
films.ForEach(print);
}
}
// 记录事件的本质,又记录与它的发送者和实参有关的信息,也就是你熟悉的delegate(object sender ,EventArgs e){...}
static void Log(string title, object sender, EventArgs e)
{
Console.WriteLine("Event: {0}", title);
Console.WriteLine(" Sender: {0}", sender);
Console.WriteLine(" Arguments: {0}", e.GetType());
foreach (PropertyDescriptor prop in
TypeDescriptor.GetProperties(e)) // PropertyDescriptor属性描述符
{
string name = prop.DisplayName;
object value = prop.GetValue(e);
Console.WriteLine(" {0}={1}", name, value);
}
}static void Main()
{
Button button = new Button();
button.Text = "Click me";
button.Click += (src, e) => Log("Click", src, e);
button.KeyPress += (src, e) => Log("KeyPress", src, e);
button.MouseClick += (src, e) => Log("MouseClick", src, e);Form form = new Form();
form.AutoSize = true;
form.Controls.Add(button);
Application.Run(form);
}
表达式树:.net3.5的表达式树提供了一种抽象的方式将一些代码表示成一个对象树,只适用于表达式,表达式树主要在
linq中使用:C#3对于将lamabda表达式转化成表达式树提供了内建的支持,但在讨论这个问题之前,首先
应理解在没有使用任何编译器技术的情况下,它们是如何与.net framwork 融合为一体的:
///
// 一个非常简单的表达式的树
class FirstExpressionTree
{
static void Main()
{
Expression firstArg = Expression.Constant(2);
Expression secondArg = Expression.Constant(3);
Expression add = Expression.Add(firstArg, secondArg);Console.WriteLine(add);
}
}
//编译并执行一个表达树:// Expression 与LambdaExpression<TDelegate>类的区别在于,泛型类以静态类型的方式标识了它是
// 什么种类的表达式,也就是说她确定了返回类型和参数,很明显,这用是TDelegate类型参数来表示的,它必须
// 是一个委托类型 ,
static void Main()
{
Expression firstArg = Expression.Constant(2);
Expression secondArg = Expression.Constant(3);
Expression add = Expression.Add(firstArg, secondArg);// Func<int>不获取任何参数,返回一个整数的委托
Func<int> compiled = Expression.Lambda<Func<int>>(add).Compile();
Console.WriteLine(compiled());
}
//首先表达式树只能表示单一的表达式,她们不能表示完整的类,方法甚至语句,其次,C#通过lamabda表达式直接在语言中支持表达式树:
// 用lambda表达式创建表达式树:
//注意,并不是所有的lambda表达式可以转换成表达式树
class LambdaExpressionToExpressionTree
{
static void Main()
{
Expression<Func<int>> return5 = () => 5; //() => 5是lambda表达式
Func<int> compiled = return5.Compile();
Console.WriteLine(compiled());
}
}//较为复杂的表达式树:
class LambdaExpressionWithParametersToExpressionTree
{
static void Main()
{
Expression<Func<string, string, bool>> expression = (x, y) => x.StartsWith(y);var compiled = expression.Compile();
Console.WriteLine(compiled("First", "Second"));
Console.WriteLine(compiled("First", "Fir"));
}
}//较为复杂的表达式树:
class LambdaExpressionWithParametersToExpressionTree
{
static void Main()
{
Expression<Func<string, string, bool>> expression = (x, y) => x.StartsWith(y);var compiled = expression.Compile();
Console.WriteLine(compiled("First", "Second"));
Console.WriteLine(compiled("First", "Fir"));
}
}
//用代码构造一个方法调用表达式树:
//C虽然C#3编译器在编译好的代码中会使用与代码清单9-10相似的代码来构造表达式树
class MethodCallExpressionTree
{
static void Main()
{
MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
var target = Expression.Parameter(typeof(string), "x");
var methodArg = Expression.Parameter(typeof(string), "y");
Expression[] methodArgs = new[] { methodArg };
// 以上代码:构造方法调用一个表达式树:Expression call = Expression.Call(target, method, methodArgs); //以上部件创建调用表达式call
var lambdaParameters = new[] { target, methodArg };
var lambda = Expression.Lambda<Func<string, string, bool>>(call, lambdaParameters);var compiled = lambda.Compile(); //将call转换成lambda表达式
Console.WriteLine(compiled("First", "Second"));
Console.WriteLine(compiled("First", "Fir"));
}
}// 总结lamada表达式提供了编译时检查的能力,而表达树将执行模型从你所需的逻辑中提取出来:
// linq to object 和linq to sql// linq to object是含有lamada表达式的C#查询代码-->C#编译器-->使用 委托的IL--->委托直接在CLR执行--->查询结果
// linq to sql 是含有lamada表达式的C#查询代码-->C#编译器-->使用表达树的IL--->LINQ TO SQL provider-->动态SQL--->在数据库处执行并取回结果----查询结果://----类型推断与重载决策发生的改变:以下代码C3#能通过,而C#不行的:
//C#2的类型推断规则是单独针对每一个实参来进行的,没有办法将从一个实参推断出来的类型直接用于另一个实参:
class ConversionWithTypeInference
{
static void PrintConvertedValue<TInput, TOutput>
(TInput input, Converter<TInput, TOutput> converter)
{
Console.WriteLine(converter(input));
}
static void Main()
{
PrintConvertedValue("I'm a string", x => x.Length);
}
}// 展示了貌似能编译,但不符合C#2类型判断规则的一些示例代码
class ReturnTypeInference
{
delegate T MyFunc<T>();//声明了.net2.0中没有的FUNC(T);static void WriteResult<T>(MyFunc<T> function)
{
Console.WriteLine(function());
}static void Main()
{
WriteResult(delegate { return 5; }); // // C#3比起C#2的巨大改变:所有方法的实参在C#3中是以"团队"的形式来工作的:
//两个解决的办法:
//a:要么显式指定类型的实参(就象编译器推荐的那样)
WriteResult<int>(delegate { return 5; });
// 将匿名方法强制转换为一个具体的委托类型:
WriteResult((MyFunc<int>)delegate { return 5; });
}
class OverloadingByDelegateReturnType
{
static void Execute(Func<int> action)
{
Console.WriteLine("action returns an int: " + action());
}static void Execute(Func<double> action)
{
Console.WriteLine("action returns a double: " + action());
}static void Main()
{
Execute(() => 1); //用委托lamada表达式转换成func<int>或f<double>
//在C#2中是会有错误的:
//但在C#3中最终会选中参数为func<int>的方法:额外的添加的规则:
// 如果一个匿名函数能转换成参数列表相同,但返回类型不同的两个委托类型,就根据从
//"推断的返回类型"到"委托的返回类型"的转换来判定那个委托转换"更好"
}
}
}}
-
LAMADA表达式
2018-09-06 21:59:03Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。... -
C++11 Lamada表达式
2018-06-22 11:17:25Lamada表达式是C++11最重要也是最常用的特性之一。Lamada来源于函数式编程的概念,也是现代编程语言的一个特点。 Lamada表达式定义 下图展示出了C++ Lamada表示的组成部分: 其中: ① 指明捕获列表 ② ... -
jsp中使用lamada表达式
2019-05-28 14:15:17在jsp页面中使用了lamada表达式导致如下报错: 以为是servlet或者jsp的包的问题,后面排查发现是jsp中使用了lamada表达式引起。 解决: 1.使用其他方法代替lamada表达式 2.升级tomcat(当前使用apache-tomcat-... -
jdk1.8新特性之lamada表达式
2020-06-14 10:46:55jdk1.8新特性之lamada表达式什么是lamada表达式为什么用lamada表达式为什么用lamada表达式函数式接口功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个... -
C# Lamada表达式的一些理解
2020-08-08 11:23:47我对Lamada表达式的理解 随着对C#语言的不断深入,开发更简洁清晰的代码是我的下一个目标 Lamada表达式之前是在JS中碰见过,但是一直没有对其深入理解,这篇文章就算是记录一下零碎的理解过程。欢迎讨论,我会不断... -
Java 8——Lamada表达式
2019-03-02 12:04:37利用java8 的lamada表达式,可以用简洁高效的代码来实现一些数据处理。 (1)List操作 (2)Map操作 (3)List和Map互换 -
Java8 lamada 表达式
2018-03-27 18:09:14Java8 lamada 表达式 参考资料出自 http://www.runoob.com/java/java8-lambda-expressions.html /** * Created by Allen on 2018/3/27. */ public class TestLamada { public static void main(String[] ... -
函数式编程与lamada表达式
2020-04-04 23:02:21由于在前面分析Map接口的时候,涉及到lamada表达式,而网上的资料大多比较杂,并且不全面,因此决定自己写一篇,并在最后附上使用比较全的博客链接 -
【Java杂记】Lamada:stream流+lamada表达式操作集合
2020-10-10 00:18:43Lamada 表达式到底什么呢?一般指匿名函数,常有以下两种形式: () -> ~,比如 x -> System.out.println(x); () -> { },比如 (a, b) -> { int x = a + b; return x;} Lamada 表达式有什么呢?一般... -
Android使用Lamada表达式
2016-12-06 11:11:15Android使用Lamada表达式标签(空格分隔): 工具使用1.APP gradle apply plugin: 'com.android.application' apply plugin: 'me.tatarka.retrolambda' ..... buildTypes { ... compileOptions { ... -
Java8 Lamada表达式使用总结
2021-01-22 16:02:31Java8 Lamada表达式使用总结一、概述1、基础数据类型二、使用1、遍历forEach2、过滤filter3、转换map\mapToInt等4、拼接join5、去重distinct6、统计count7、排序sort8、分组groupingBy9、校验Optional10、包含... -
java的lamada表达式常用例子
2019-08-13 14:48:21最近学习了lamada的常见使用方法,发现其实lamada表达式的确是匿名内部类一种简便的使用,话不多说,如下举例 Student studentww=new Student("wangwu",99,"code"); Student studentclr=new Student("clr",100,... -
C#基础加强篇---委托、Lamada表达式和事件(中)
2015-03-21 02:28:002.Lamada表达式 C#共有两种匿名函数:匿名方法和Lamada表达式。在2.0之前的C#版本中,创建委托的唯一方法是使用命名方法。C#2.0中引入了匿名方法,匿名方法就是没有名称的方法。从C#3.0开始,就可以使用一种新语法... -
net Lamada表达式转匿名对象
2019-11-06 17:40:12将Expression<Func<T>>表达式转为Expression, object>> -
Linq学习工具及Lamada表达式
2013-08-20 15:17:00好东西。转载一个。以备学习 Linq学习工具:http://www.linqpad.net/ Lamada表达式: Func<int, int, int> IntPow = (x, y) => ... -
在DataStream中的泛型中含有Tuple时,使用Lamada表达式时报错
2021-01-12 10:42:25今天在使用Flink 时泛型采用的时Tuple,在后面进行算子操作时,采用了lamada表达式发现,代码运行时报以下错误 The generic type parameters of ‘Tuple3’ are missing. In many cases lambda methods don’t ... -
【JAVA】 JAVA8 中匿名类和Lamada表达式对比
2018-11-04 20:21:40使用Lamada表达式 更加简洁 直观; interface judgeOne{ public boolean judge(Apple apple); } class Appleselecter{ //行为参数化 public List<Apple> getAppleList(List<Apple>...