java过滤关键字函数_第6章 扩展函数与属性

《Kotlin 项目实战教程》

第6章 扩展函数与属性

在使用Java的时候,我们经常使用诸如StringUtil, DateUtil等等一堆工具类,代码写起来也比较冗长。举个例子,获取一个字符串的第一个字符值、最后一个字符值。如果我们用Java代码来写,通常是要先声明一个StringUtil类,然后在里面写相应的工具方法,代码可以是下面的这个样子

package com.easy.kotlin;

import static java.lang.System.out;

public class StringUtil {

/**

* 获取str的第一个字符值

*

* @param str

* @return

*/

public static String firstChar(String str) {

if (str != null && str.length() > 0) {

return str.charAt(0) + "";

}

return "";

}

/**

* 获取str的最后一个字符值

*

* @param str

* @return

*/

public static String lastChar(String str) {

if (str != null && str.length() > 0) {

return str.charAt(str.length() - 1) + "";

}

return "";

}

public static void main(String[] args) {

String str = "abc";

out.println(StringUtil.firstChar(str)); // a

out.println(StringUtil.lastChar(str)); // c

}

}

我们可以看到 StringUtil.firstChar(str) 这样的调用方式不够简单直接。能不能直接这样调用

"abc".firstChar()

"abc".lastChar()

非常遗憾的是,在Java中我们无法给String类添加一个自定义方法。因为String类是JDK中内置的基础类,而且为final,不能修改。所以,Java程序员通常使用这样的一个变通的方法:开发一个StringUtil类,在里面封装所需要的String操作的方法。而不是修改或继承String类。

而情况到了Kotlin里面,就完全不一样了——我们完全可以自由扩展任何类的方法和属性。在不修改原类的情况下, Kotlin能给一个类扩展新功能而无需继承该类。

本章我们介绍Kotlin的扩展函数和属性。

6.1 扩展函数

Kotlin中提供了非常简单使用的扩展函数功能。我们可以为现有的类自由添加自定义的函数 。

6.1.1 给String类扩展两个函数

例如,我们现在给String类扩展两个函数:lastChar() 和 firstChar() , 实现代码如下

package com.easy.kotlin

fun String.lastChar(): String {

if (this.length == 0) {

return ""

}

return this[this.length - 1].toString()

}

fun String.firstChar(): String {

if (this.length == 0) {

return ""

}

return this[0].toString()

}

扩展函数的语法,我们用下图来简单说明

f9dced710fe07e59c7f1b2abf8d97e57.png

然后,我们就可以在代码中直接调用了

fun main(args: Array) {

val str = "abc"

println(str.firstChar()) // a

println(str.lastChar()) // c

}

如果在其他package路径下面,需要 import 导入扩展函数

package com.easy.kotlin.tutorial // 跟扩展函数不在同一个包路径下面

import com.easy.kotlin.firstChar // 导入扩展函数 firstChar

import com.easy.kotlin.lastChar// 导入扩展函数 lastChar

fun main(args: Array) {

val str = "abc"

str.firstChar() // 这样的调用方式要比 StringUtil.firstChar(str) 简单优雅许多

str.lastChar()

}

6.1.2 给 List 类扩展一个过滤函数

在上一章中我们介绍过List的filter函数。那么这个 filter 函数是怎样实现的呢? 如果我们自己来给List类扩展一个过滤函数,应该怎样去做呢?下面我们就来介绍。

为了更加深刻体会到 Kotlin 扩展功能的简单优雅性,我们先来看看在Java中是怎样实现的吧!首先,我们会去声明一个ListUtil 类,里面实现一个 List filter(List list, Predicate p) 方法,代码如下

public class ListUtil {

/**

* 根据谓词p 过滤 list 中的元素

*

* @param list

* @param p

* @return

*/

public List filter(List list, Predicate p) {

List result = new ArrayList<>();

for (T t : list) {

if (p.predicate(t)) {

result.add(t);

}

}

return result;

}

}

其中,Predicate 接口声明如下

interface Predicate {

Boolean predicate(T t);

}

然后,我们在代码中这样使用这个 filter 方法

public static void main(String[] args) {

List list = Arrays.asList(new Integer[] {1, 2, 3, 4, 5, 6, 7});

ListUtil listUtil = new ListUtil(); // 声明ListUtil对象

List result = listUtil.filter(list, (it) -> it % 2 == 1); // lambda 表达式

out.println(result); // [1, 3, 5, 7]

}

为了调用 filter 方法,我们还要声明一个ListUtil对象,费事。能不能直接像下面这样调用?

list.filter { it % 2 == 1 }

答案是肯定的,只不过是在Kotlin中,而不是在Java中。

我们就来使用Kotlin的扩展函数为List扩展一个filter函数,代码如下

fun List.filter(predicate: (T) -> Boolean): MutableList {

val result = ArrayList()

this.forEach {

if (predicate(it)) {

result.add(it)

}

}

return result

}

这个函数的签名稍微有点复杂,我们用下图来形象化地简单说明

ec022a4fa311680e143b10a6e5c3ead3.png

然后,我们在代码中只需要这样调用即可

val list = mutableListOf(1, 2, 3, 4, 5, 6, 7)

val result = list.filter {

it % 2 == 1

}

println(result) // [1, 3, 5, 7]

Kotlin的标准库API中使用扩展的功能,通过扩展Java的API,提供了大量的实用简单的函数。我们将在后面的关于文件IO、正则表达式、多线程等相关主题中介绍。

6.2 扩展属性

除了扩展一个类的函数,我们还可以扩展类属性。例如,我们给 MutableList 扩展两个属性:firstElement 和 lastElement , 实现代码如下

var MutableList.firstElement: T

get() {

return this[0]

}

set(value) {

this[0] = value

}

var MutableList.lastElement: T

get() {

return this[this.size - 1]

}

set(value) {

this[this.size - 1] = value

}

上面的代码中的扩展属性的语法说明如下图所示

eaf524a486234db799bea682adecd2d1.png

然后,我们就可以在代码中直接使用扩展的属性了

val list = mutableListOf(1, 2, 3, 4, 5, 6, 7)

println("list = ${list}") // list = [1, 2, 3, 4, 5, 6, 7]

println(list.firstElement) // 调用getter 函数 , 值是 1

println(list.lastElement) // 7

list.firstElement = -1 // 调用 setter 函数

list.lastElement = -7

println("list = ${list}") // list = [-1, 2, 3, 4, 5, 6, -7]

println(list.firstElement) // -1

println(list.lastElement) // -7

扩展属性允许定义在类或者kotlin文件中,不允许定义在函数中。

6.3 扩展中的this关键字

我们有注意到,在上面的List的扩展函数filter的实现中,我们有用到一个this关键字

this.forEach {

if (predicate(it)) {

result.add(it)

}

}

这里的 this 指的是 接收者对象(receiver object), 也就是调用扩展函数时, 在点号( . )之前指定的对象实例。

本章小结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值