kotlin语法学习总结(一)常用函数

目录

takeIf

takeUnless

filter

forEach

firsrt

fold


takeIf

/**
 *return:返回值,如果传入的函数predicate的返回值为true则将T这个对象返回,否则返回null
 */
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
    contract {
        callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
    }
    return if (predicate(this)) this else null
}

分解:
T:为任意对象
predicate: 传入的函数或表达式
(T) -> Boolean:函数的类型,即将T对象传入,返回一个布尔值

例:
(1)常见的if判断
   java:
   int a;
   if(a>5){ doSomething();  } 

   kotlin:
   var a
   takeIf{ a>5 }?.apply{ doSomething() }

(2)判断一个对象的属性  
   java:
   if(obj != null && obj.name == "小花"){
       doSomething();
   }
   
   kotlin:
   if(obj?.name == "小花"){
     doSomething()
   }
   或:
   obj.takeIf(obj.name == "小花")?.apply{ doSomething() }
   当然takeIf里的obj对象可以用it代替
   obj.takeIf(it.name == "小花")?.apply{ doSomething() }

总结:因为返回的是调用对象自己,所以可以进行链式调用

takeUnless

/**
 * 与takeIf用法基本一致,只是在返回处做了取反操作,即predicate为true返回null,否则返回T对象自己
 */
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? {
    contract {
        callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
    }
    return if (!predicate(this)) this else null
}

filter

/**
 * 过滤器
 * 返回符合predicate过滤条件的list
 * 
 */
public inline fun <T> Array<out T>.filter(predicate: (T) -> Boolean): List<T> {
    return filterTo(ArrayList<T>(), predicate)
}

分解:
<T> Array<out T> :一个T或T子类的数组对象
predicate: 条件函数,即fun(T t){return boolean}
(T) -> Boolean : 函数类型,传入数组对象中的一个元素,返回一个布尔值
List<T> : 返回值类型,实现了List接口的子类

它直接返回了filterTo函数,主要处理逻辑在filterTo中

public inline fun <T, C : MutableCollection<in T>> Array<out T>.filterTo(destination: C, predicate: (T) -> Boolean): C {
    for (element in this) if (predicate(element)) destination.add(element)
    return destination
}

简单易懂,将满足条件(predicate)的数组添加到到list里返回了

例:
java:
public class Student{
    String name;
    int age;
    public Student(String name,int age){}
}

Student[] arr;
List<Student> list = new ArrayList();
Student stu1 = new Student("小李",28)
Student stu2 = new Student("小王",15)
Student stu3 = new Student("小赵",23)
...
arr = new Student[]{stu1,stu2,stu3, …};

for(Student std : arr){
   if(std.age > 20){
     list.add(std) 
   }
}

kotlin:
 
//省略student实体类

var list = arr.filter{it.age > 20}


forEach

/// 以IntArray.forEach为例

/**
 * 遍历数组里的每一个元素
 * 这是IntArray的一个扩展函数
 */
public inline fun IntArray.forEach(action: (Int) -> Unit): Unit {
    //遍历数组里的元素,然后将给个元素传给action函数
    for (element in this) action(element)
}

分解:
action: (Int) -> Unit:传入的参数是一个(Int) -> Unit类型的函数

Unit:forEach函数的返回类型

使用:
var intArray :IntArray = intArrayOf(1,2,3,4,56)
案例1:
intArray.forEach({
            println(it)
        })
案例2:
intArray.forEach{
            println(it)
        }
案例3:
intArray.forEach(::print)

从案例1到案例3是语法上的演变过程,因为println的重载之一的类型的(Int) -> Unit,所以可以直接将println函数的引用直接传入forEach,同理自定义的(Int) -> Unit类型的函数都可以这样使用

firsrt

 * 返回可迭代对象中符合predicate条件的第一个元素
 * 若没有符合条件的元素,则抛出异常
 * @throws [NoSuchElementException] if no such element is found.
 */
public inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T {
    for (element in this) if (predicate(element)) return element
    throw NoSuchElementException("Collection contains no element matching the predicate.")
}

分解:
inline fun:是一个内联函数
<T> Iterable<T> :实现了Iterable接口的对象才能使用first函数
predicate: (T) -> Boolean  :返回布尔值得函数或lamada表达式

例:
  var list :List<Int> = listOf<Int>(1,2,2,2,3,4,5)

  val first :Int = list.first { it == 2 }
  当第一个2满足条件时,直接就返回了第一个2

fold

/**
 * 给定一个初始值initial
 * 将初始值与这个函数的调用者(可迭代对象)中的元素,做动作累加(operation)操作
 * 最后将动作累加后的结果返回
 */
public inline fun <T, R> Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R {
    //将初始值赋值给临时对象accumulator
    var accumulator = initial
    //遍历所有元素
    for (element in this) 
    //每个元素在之前的基础上做动作累加
    accumulator = operation(accumulator, element)

    //注意return不在循环体中
    return accumulator
}

分解:
<T, R> Iterable<T> :调用fold函数的对象需要实现Iterable接口,T,R为两个泛型
initial: R   :给定的一个初始值
operation: (acc: R, T) -> R   :需要做的累加动作,累加动作不是单指做加法,这是基于上个值做操作的统称

案例1:依次累乘
    val arr = intArrayOf(3, 5, 4, 7, 10)

    val fold = arr.fold(2) { acc, i -> acc * i }
    println(fold)

    *为避免歧义,这个例子中累加动作为做乘法
     即:initial = 2
     累加动作为 R * T
     运行过程为:
     acc = 2 * 3
     acc = 6 * 5   ,6即(上次的结果 2*3)
     acc = 30 * 4
     acc = 120 * 7
     acc = 840 * 10
     acc = 8400
     返回8400
 
案例2:将集合拼接成字符串
 
    println((0..6).fold(StringBuilder()) { acc, i ->
        acc.append(i).append(",")
    })

总结:operation(累加动作)是由使用者自己定义的运算逻辑

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值