c await和java_C# vs Java:C# 五个不可替代的特性瞬间秒杀 Java

原标题:C# vs Java:C# 五个不可替代的特性瞬间秒杀 Java

如果我们可以同时拥有 C# 和 Java 世界的最好特性,那会是什么样呢?

完美的编程语言并不存在,我希望我们可以在这一点上达成一致。开发新语言往往是为了克服另一种语言的弊端,又不可避免的在某些方面上健壮一些,却在另一些方面上存在不足。

C# 与 Java 都起源于 C/C++ 语言,他们在面向对象方面有许多相似之处。除了 Java JVM 和 C# .NET CLR 有许多相同结构上的相似性之外,他们各自的开发团队都有各自的发展方向,他们关注的是各自的语言应该成为什么样子。

我们并不想纠结于某一个语言比另一个语言好,我们只想罗列出 C# 开发者能用到而 Java 中没有的那些特性而已。

下面我们开始吧。

LINQ

LINQ (Language-Integrated Query,语言集成查询) 于 2007 年引入到 C#,以帮助开发人员从各种数据源查询数据。使用它,我们可以在无需考虑正在调用的特定数据库的语法来编写查询语句。

LINQ provider 所提供的一个组件将查询转换为下层数据源可读的格式。例如,如果我们需要从 SQL 数据库查询数据,LINQ to SQL provider 程序将把 LINQ 查询转换成 T-SQL,以便数据库可以理解它。

要在 LINQ 中执行查询操作,首先获取数据库,然后创建查询,最后执行查询。在 LINQ to Object 查询中,这可能仅像一样代码一样简单,而不是为每个循环编写嵌套的复杂迭代。

例如,我们来看看这个代码,用于在 C# 中从列表中过滤 2 位数。

首先,在不使用 LINQ 的情况下:

77c66a34fff061489f0ecda85cdd985b.png

如果使用 LINQ 查询语法形式:

a8ba04eeab30bb62acf1e25174df36b4.png

或者是方法语法形式:

d339b66bad02100f9fde10fdf9760e87.png

这里两种语法都是正确的,唯一的区别就是查询语法看起来更像是 SQL 语句而方法语法使用 lambda 表达式(当然,看起来很像我们在 Java 里写的某些代码)

综述:LINQ 所依赖的许多特性,如 lambda 表达式(就 LINQ 来说非常有用),已经在 Java 中有了等效的实现,尽管我们可以使用流和 lambda 来查询数据,但 LINQ 简化了整个过程并且移除了很多在 Java 中存在的冗余代码。

2. Struct

C# 中的结构体类似于类。实际上,一个 struct 甚至可以被认为是一个“轻量级类”,因为它可以包含构造函数、常量、方法等等。一个结构体和一个类之间最大的区别在于结构是值类型,而类是引用类型。

相比于创建类,编写结构体最重要的好处是在构造一个值类型时比在构造引用类型时更容易确保值语义。如 Microsoft 的 文档 所述,“struct 类型的变量直接包含结构体的数据,而类类型的变量包含对数据的引用。”因此,对比使用类时,使用结构体的好处之一是,从代码的其他部分更改其值的唯一方法是将其作为参考进行显式传递。

微软的开发人员 建议 对于那些小于 16 字节、生命周期短、不改变的而且不常装箱的类型,使用结构体(struct)而不是类(class)。在这种情况下,使用结构体可能会比使用类更有效率,因为它会保存在栈而不是堆中。

比如:

70614eb05a4761b00a3051c1b409b586.png

小结:很多情况下使用结构体可以节省内存分配和释放的时间,这确实很有吸引力。然而事实是值类型拥有自己的存储空间。无论结构体拥有如何明显的优点和缺点,这在 Java 中都不需要操心。

3. Async/Await

在一段代码中调用 async,或者更明确地调用方法,这个方法都会在另一个线程上执行,不会阻塞当前线程。当代码运行到 await 命令的时候,它会继续运行(await 的语句)。如果这时 async 代码还没有完成,那么执行中的程序会返回到调用点。

这有助于提高应用程序总体的响应速度,以及减少性能瓶颈。在应用程序访问 Web 和进行所有 UI 相关的活动时,使用异步程序非常重要。相对于以前的异步编程实现,使用 async/await 可以保留你代码的逻辑结构,而编译器则会担负起以前由开发者担负的重担。

示例:

edc01f59e2f8394e6a284ca2ec7b34e7.png

输出:

4dc1248c582f95b3ccaf9d2f1983235c.png

概要:CompletableFutures 无疑可以使我们更趋近于拥有等效于 C# 和 Java 所拥有的异步编程中的能力。尽管如此,使用它所带来的复杂性使其易用度不能与使用 async /await 关键字进行的实现相提并论。

4. Lazy 类

无论使用 C# 还是 Java,很多人都已经实现了延迟初始化 (或实例化),因此对象要在第一次使用的时候才会被创建。有一种常见的例子是将延迟初始化用于应用程序启动的时候加载大量对象,但实际需要初始化的对象可能只有少数几个。这种情况下,我们希望辨别哪些是不需要在这里初始化的。只初始化那些确实需要初始化的对象可以提升应用程序的性能。

小结: 最近,Lambda 表达式引入到 Java 8 之后,在 Java 中实现延迟加载(还有不少其它事情)变得更容易了。不过,在 C# 中我们可以使用语义化的 Lazy 封装类来延迟初始化任何类库或用户指定的类型。

5. 一些等价的关键词

语言中的有用功能不一定像在 C# 中的 LINQ 或 Java 中的模块一样大。这里有一些可以帮助 C# 开发人员的关键字,它们在 Java 中并没有:

a. as

C# 中的 as 关键字会尝试安全地将对象转换为某个类型,如果不能转换的话,就返回 null。与 Java 的instanceof 几乎等同,但它是一个布尔值,如果类型匹配则返回 true,否则返回 false。

b. Yield

在 C# 中使用 Yield 和 return yield 来进行自定义且状态化的迭代,不需要显式创建额外的类,也不需要创建临时集合。在 Java 中我们实现迭代最好的选择是使用外部库或使用 Java 8 引入的 Lambda 表达式。

c. var

Var 是一种隐式类型,其实际类型由编译器决定,其功能相当于写一个显式类型 (比如 int , string 等)。它除了可以减少一些按键之外, var 还允许用于匿名类型,而匿名类型在 LINQ 中很常用。我们 期待看到“var”标识 ,备受瞩目的 Java SE 9 将实现“将类型推导扩展到定义并初始化局部变量时。”

15201480058返回搜狐,查看更多

责任编辑:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值