Java面向对象基础知识之委托和lambda

作者:一指流砂~ 时间:2022-07-28 16:51:11 

委托定义类型,类型指定特定方法签名。可将满足此签名的方法(静态或实例)分配给该类型的变量,然后(使用适当参数)直接调用该方法,或将其作为参数本身传递给另一方法再进行调用。以下示例演示了委托的用法。


using System;
using System.Linq;

public class Program
{
   public delegate string Reverse(string s);

static string ReverseString(string s)
   {
       return new string(s.Reverse().ToArray());
   }

static void Main(string[] args)
   {
       Reverse rev = ReverseString;

Console.WriteLine(rev("a string"));
   }
}
  • public delegate string Reverse(string s);行创建特定签名的委托类型,在本例中即接受字符串参数并返回字符串参数的方法。

  • static string ReverseString(string s)方法与定义的委托类型具有完全相同的签名,用于实现委托。

  • Reverse rev = ReverseString;行显示可将方法分配给相应委托类型的变量。

  • Console.WriteLine(rev("a string"));行演示如何使用委托类型的变量来调用委托。

为简化开发过程,.NET 包含一组委托类型,程序员可重用这些类型而无需创建新类型。其中包括Func<>Action<>Predicate<>,可用于 .NET API 的各个位置,无需定义新委托类型。当然,从这三者的签名可以看出它们之间存在某些差异,主要影响其既定用途:

  • Action<>用于需要使用委托参数执行操作的情况。

  • Func<>通常用于现有转换的情况,也就是说需要将委托参数转换为其他结果时。最好的示例就是投影。

  • Predicate<>用于需要确定参数是否满足委托条件的情况。也可将其写作Func<T, bool>。

现在可使用Func<>委托而非自定义类型重新编写上述示例。程序将照旧继续运行。


using System;
using System.Linq;

public class Program
{
   static string ReverseString(string s)
   {
       return new string(s.Reverse().ToArray());
   }

static void Main(string[] args)
   {
       Func<string, string> rev = ReverseString;

Console.WriteLine(rev("a string"));
   }
}

对于此简单示例而言,在Main方法之外定义方法似乎有些多余。因此 .NET Framework 2.0 引入了匿名委托的概念。在其支持下,可创建“内联”委托,而无需指定任何其他类型或方法。只需在所需位置内联委托的定义即可。

例如,要进行切换并使用匿名委托筛选出只有偶数的列表,然后将其打印到控制台。


using System;
using System.Collections.Generic;

public class Program
{
   public static void Main(string[] args)
   {
       List<int> list = new List<int>();

for (int i = 1; i <= 100; i++)
       {
           list.Add(i);
       }

List<int> result = list.FindAll(
         delegate (int no)
         {
             return (no % 2 == 0);
         }
       );

foreach (var item in result)
       {
           Console.WriteLine(item);
       }
   }
}

如你所见,该委托的正文只是一组表达式,其他所有委托也是如此。但它并非单独定义,而是在调用List<T>.FindAll方法时临时引入。

但是,即使使用此方法,仍有许多可以丢弃的代码。此时就需要使用lambda 表达式。

lambda 表达式(或简称“lambda”)在 C# 3.0 中作为语言集成查询的 (LINQ) 核心构建基块被首次引入。这种表达式只是使用委托的更方便的语法。它们将声明签名和方法正文,但在分配到委托之前没有自己的正式标识。与委托不同,可将其作为事件注册的左侧内容或在各种 LINQ 子句和方法中直接分配。

由于 lambda 表达式只是指定委托的另一种方式,因此应可重新编写上述示例,令其使用 lambda 表达式而不是匿名委托。


using System;
using System.Collections.Generic;

public class Program
{
   public static void Main(string[] args)
   {
       List<int> list = new List<int>();

for (int i = 1; i <= 100; i++)
       {
           list.Add(i);
       }

List<int> result = list.FindAll(i => i % 2 == 0);

foreach (var item in result)
       {
           Console.WriteLine(item);
       }
   }
}

在前面的示例中,所使用的 Lambda 表达式为i => i % 2 == 0。再次强调,它只是使用委托的一种非常方便的语法,因此其实际行为与使用匿名委托时相同。

再次强调,lambda 只是委托,这意味着可将其顺利用作事件处理程序,如以下代码片段所示。


public MainWindow()
{
   InitializeComponent();

Loaded += (o, e) =>
   {
       this.Title = "Loaded";
   };
}

此上下文中的+=运算符用于订阅事件。

来源:https://www.cnblogs.com/xuwendong/p/10885639.html

标签:Java,面向对象,委托,lambda
0
投稿

猜你喜欢

  • springboot基于Redis发布订阅集群下WebSocket的解决方案

    2023-07-14 04:37:45
  • Java Mybatis框架多表操作与注解开发详解分析

    2023-12-04 17:15:14
  • Android实现 EditText输入手机号空格功能

    2021-09-17 00:29:27
  • java获取中文拼音首字母工具类定义与用法实例

    2023-07-14 08:23:55
  • 图文浅析Java序列化和反序列化

    2022-08-03 17:46:59
  • Spring refresh()源码解析

    2022-09-04 18:45:52
  • 深入探究Java线程的状态与生命周期

    2021-10-01 17:44:10
  • JAVA过滤标签实现将html内容转换为文本的方法示例

    2022-10-16 21:02:40
  • springboot中使用@Transactional注解事物不生效的坑

    2021-10-03 10:01:47
  • IntelliJ IDEA使用教程从入门到上瘾(2019图文版)

    2023-03-30 17:00:49
  • java中ResultSet遍历数据操作

    2022-06-13 05:02:13
  • Android之在linux终端执行shell脚本直接打印当前运行app的日志的实现方法

    2021-06-12 23:41:08
  • 使用JPA双向多对多关联关系@ManyToMany

    2021-12-04 03:37:12
  • LZ77压缩算法原理的理解

    2023-01-16 17:48:02
  • springsecurity 企业微信登入的实现示例

    2023-06-16 16:39:35
  • SpringBoot整合liquibase及liquibase生成初始化脚本的方式

    2023-07-29 11:53:18
  • Android添加用户组及自定义App权限的方法

    2022-09-15 20:08:53
  • Java Vector实现班级信息管理系统

    2023-11-25 03:09:09
  • 手写Java LockSupport的示例代码

    2021-11-05 07:00:39
  • Java中接口和抽象类的区别详解

    2022-09-28 15:21:19
  • asp之家 软件编程 m.aspxhome.com