原

Kotlin学习(4)Lambda

2017年09月26日 21:00:03 gwt0425 阅读数:551
 

记住Lambda的本质,还是一个对象。和JS,Python等不同的是,Kotlin里的Lambda不是方法,而是一个简化了的对象。

此外,Kotlin里面的没有匿名函数这一说,函数也不是传统的对象。

看看Kotlin的Lambda

//Java
button.setOnClickListener(v -> {//...}) //Kotlin
button.setOnClickListen{//...}

一个Lambda函数

it是一个lamdba隐含对象,可能是Iterable的简写吧

data class Person(val name: String, val age: Int)

fun main(vararg args: String){
val people = listOf<Person>(
Person("Alice",29),
Person("Bob",31)
) //使用隐含对象
println(people.maxBy { it.age })
//使用成员对象引用
println(people.maxBy(Person::age))
//类Java
println(people.maxBy{ p: Person -> p.age})
}

Lambda句法

//Java
static IntBinaryOperator add = (x, y) -> x + y; public static void main(String...args){
add.applyAsInt(1,2)
} //Kotlin
val sum = { x: Int, y: Int -> x + y } fun main(vararg args: String){
sum(1,2)
}

咋一看挺迷惑的,需要看看Java中的写法

因为上面说了Lambda是个对象,那么对象能像函数一样调用呐?

证实了我们的观点,确实是个对象,sum()应该是sum.invoke()的语法糖吧

直接调用Lambda

{ x: Int, y: Int -> x + y }(1,2)

//run适用于无参数的Lambda
run { print(24)}

看一个例子

transform申明要一个Lambda参数

public fun <T> Iterable<T>.joinToString(
separator: CharSequence = ", ",
prefix: CharSequence = "",
postfix: CharSequence = "",
limit: Int = -1,
truncated: CharSequence = "...",
transform: ((T) -> CharSequence)? = null): String {
return ...
}

在Lambda中使用可变变量

在Java中,Lambda中不能使用变量,如下

public static void main(String...args){
int i = 0;
Runnable r = () -> {
i++;//会报错
};
} //只能这么做
static class I{
public static int i = 0;
}
public static void main(String...args){
Runnable r = () -> {
I.i++;
};
}

但是在Kotlin中可以

var count = 0
val inc = { count++ }
  • 1
  • 2

成员引用

可以视为Java反射包中的Field和Method

data class Person(val name: String, val age: Int)
Person::age//property age fun sulate() = println("aaa")
val a = run(::salute)//function add //构造器引用
val createPerson = ::Person
val p = createPerson("Alice", 29) val personAgeFunction = Person::age
println(personAgeFunction(p)) //29 val thisPersonAgeFunction = p::age
println(thisPersonAgeFunction()) //29

最后两个例子可能有些疑惑,但本质personAgeFunction还是一个对象,像函数一样调用还是一个语法糖(personAgeFunction.get())


函数式API

典型的声明式编程,和SQL语句有共同之处。语义很好理解,不解释了

  • filter
  • map: map是将集合中的每个元素变成另一种A->B
  • filterKeys
  • mapKeys
  • filterValues
  • mapValues
  • all
  • any
  • count
  • find
  • groupBy
    val people = listOf<Person>(
Person("a",19),
Person("b",28),
Person("c",19),
Person("d",20)
) val result = people.groupBy { it.age }
println(result)
println(result.javaClass)
/*
{19=[Person(name=a, age=19), Person(name=c, age=19)],
28=[Person(name=b, age=28)],
20=[Person(name=d, age=20)]} class java.util.LinkedHashMap
*/
  • flatMap: flatMap将每个元素变成一个集合再合并这些集合A->[1,2…]
  • flatten
  • toList()
  • toSet()
  • asSequence: 类似于Java8的stream()
//传统链式调用,会产生一个map的结果和一个filter的List结果
//当集合很大时,有很大的性能开销
val result = people.map { it.age }
.filter { it > 20 } //改为使用asSequence(),最后别忘了加上toList()
val result = people.asSequence()
.map { it.age }
.filter { it > 20 }
.toList()

创建Sequence

val number = generateSequence(0) { it + 1 }
val numbersTo100 = number.takeWhile { it <= 100 }
println(numbersTo100.sum())

使用map函数对集合进行操作

fun main(args: Array<String>) {
val list:Array<Int> = arrayOf(1,2,3,4,5,6,7,8)

val newList = list.map {
it*5+10
}

val doubleList = list.map(Int::toDouble)

newList.forEach(::println)
doubleList.forEach(::println)
}
使用flatMap对集合数据进行合并成一个集合

fun main(args: Array<String>) {
val list = arrayOf(
1..10,
20..30,
50..100
)

val mergeList = list.flatMap {
it.map {
"No.$it"
}
}

mergeList.forEach(::println)
}
使用reduce对集合进行计算操作

fun main(args: Array<String>) {
val list = arrayOf(
1..10,
20..30,
50..100
)

val mergeList = list.flatMap { it }
mergeList.forEach(::println)
println("总和:${mergeList.reduce(Int::plus)}")
println("总和:${mergeList.reduce { acc, i -> acc + i }}")

/**
* 方式1
*/
(0..6).map {
factorial(it)
}.forEach(::println)

/**
* 方式2
*/
(0..6).map(::factorial).forEach(::println)

}

/**
* 求阶乘
*/
fun factorial(int: Int): Int {
if (int == 0) return 1
return (1..int).reduce { acc, i -> acc * i }
}
使用fold对集合进行自定义计算

fun main(args: Array<String>) {
/**
* 对集合进行转化和拼接
*/
val _str: String = (0..10).joinToString(",")
println(_str)

/**
* 添加一个初始值
* 打印结果=》9
*/
println((0..1).fold(8) { acc, i ->
acc + i
})

/**
* 添加一个StringBuilder的初始值与集合中的元素进行计算操作
*/
val _str1 = (0..5).fold(StringBuilder()) { acc, i ->
acc.append(i).append(",")
}
println(_str1)

}

---------------------

 

kotlin函数api的更多相关文章

  1. 065 updateStateByKey的函数API

    一:使用场景 1.应用场景 数据的累加 一段时间内的数据的累加 2.说明 每个批次都输出自己批次的数据, 这个时候,可以使用这个API,使得他们之间产生联系. 3.说明2 在累加器的时候,起到的效果和 ...

  2. HTML5 Audio标签方法和函数API介绍

    问说网 > 文章教程 > 网页制作 > HTML5 Audio标签方法和函数API介绍 Audio APIHTML5HTML5 Audio预加载 HTML5 Audio标签方法和函数 ...

  3. MySQL Crash Course #05# Chapter 9. 10. 11. 12 正则.函数. API

    索引 正则表达式:MySQL only supports a small subset of what is supported in most regular expression implemen ...

  4. Unix/Linux系统时间函数API

    首先说明关于几个时间的概念: 世界时:起初,国际上的标准时间是格林尼治标准时间,以太阳横穿本初子午线的时刻为标准时间正午12点.它根据天文环境来定义,就像古代人们根据日晷来计时一样,如下图: 原子时: ...

  5. Kotlin 函数

    至于什么函数,在计算机里面就是一个密闭的执行程序的代码块(个人理解) 我们先来看看什么是函数 fun main(agrs : Array<String>) { println(" ...

  6. Atitit.跨平台预定义函数 魔术方法 魔术函数 钩子函数 api兼容性草案 v2 q216  java c# php js.docx

    Atitit.跨平台预定义函数 魔术方法 魔术函数 钩子函数 api兼容性草案 v2 q216  java c# php js.docx 1.1. 预定义函数 魔术方法 魔术函数是什么1 1.2. & ...

  7. Kotlin函数与Lambda表达式深入

    Kotlin函数: 关于Kotlin函数在之前也一直在用,用fun来声明,回忆下: 下面再来整体对Kotlin的函数进行一个学习. 默认参数(default arguments): 先来定义一个函数: ...

  8. kotlin函数加强

    在之前已经接触过了kotlin的函数了,这里再次加强学习下它,下面开始吧! Kotlin函数编写规则: 对照函数来理解其写法: 演练巩固: ①.编写函数, 实现四则运算. 接着来实现其它三个运算: 然 ...

  9. Kotlin函数中默认参数

    Java不支持默认参数.但kotlin函数却可以 package loaderman.demo class Customer(var name:String ="name"){// ...

随机推荐

  1. day23面向对象编程基础

    面向对象编程基础1.面向过程的编程思想    核心过程二字,过程指的是解决问题的步骤,即先干什么\再干什么\后干什么    基于该思想编写程序就好比在设计一条流水线,是一种机械式的思维方式    优点 ...

  2. v修 pp改n属性

    通过修改DNS达到不FQ也能访问Google(仅限于Google)   一.前言 不知道各位小伙伴们现在用的搜索引擎是用Google搜索还是百度搜索呢?但我个人还是比较极力推荐用Google搜索的,首 ...

  3. 零基础学习python_easygui(35课)

    今天学习的内容我觉得还是很有意思的,当然我主要也是从这个网址学的:http://bbs.fishc.com/thread-46069-1-1.html,大家可以直接看这个网址进行学习,当然也可以看看我 ...

  4. IDEA搭建Spring框架环境

      一.spring 框架概念 spring 是众多开源 java 项目中的一员,基于分层的 javaEE 应用一站式轻量 级开源框架,主要核心是 Ioc(控制反转/依赖注入) 与 Aop(面向切面) ...

  5. mybatis一(常用配置信息和获取插入后id)

    <!--配置文件--><?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE conf ...

  6. 在keil调用Notepad++

    先打开keil, 新建一个 取名为notepad 选择notepad++的安装路径 设置参数 保持后可以看多了notepad的选项 运行当前的文件在notepad++打开

  7. arguments.callee 和 caller

    arguments arguments它是一个类数组对象,包含着传入函数中的所有参数.虽然 arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,该属性是一个指 ...

  8. Java快速开发平台——JEECG 3.7.8 版本发布!我们的目标是有鱼丸也有粗面

    JEECG 3.7.8 版本发布,多样化主题UI满足你不同的需求 导读                    ⊙平台性能优化,速度闪电般提升           ⊙提供5套新的主流UI代码生成器模板( ...

  9. JAVA版开源微信管家—JeeWx捷微3.2版本发布,支持微信公众号,微信企业号,支付窗、小程序

    JeeWx捷微3.2微信企业号升级版本发布^_^ JeeWx捷微V3.2——多触点管理平台(支持微信公众号,微信企业号,支付窗.小程序)   JeeWx捷微V3.2.0版本引入了更多新特性,支持微信公 ...

  10. 02-body标签中相关标签-1

    主要内容: 字体标签: h1~h6.<font>.<u>.<b>.<strong><em>.<sup>.<sub> ...