解构
fun main(args : Array<String>){
val user = User(12,"name")
val (age,name) = user
println(age)
println(name)
}
calss User(var age:Int,var name:String){
operator fun component1() = age
operator fun component2() = name
}
operator : 将一个函数标记为重载一个操作符或者实现一个约定
应用场景:在遍历一个map集合的时候可以使用解构,可以同时获取到key 和 vul, 例如下
val map:Map<String,String> =mapOf<String,String>{"key" to "key","vul" to "vul"}
for((k,v) in map){
println("key=$key vul=$vul")
}
循环与集合操作符
循环
var count:Int
for(count = 0; count < 10; count++){
}
上述类似java的for循环,在kotlin 中是没有的。但kotlin 提供了更强大的。如下
for(i in 1..10){
println(i)
}
for(i in 1 until 10){
println(i)
}
for(i in 10 downTo 1){
println(i)
}
for(i in 1..10 setp 2){
println(i)
}
repeat(10){
println(it)
}
val list : ArrayList<String> =arrayListOf<String>{"a","b"}
for(str in list){
println(str)
}
for((index,str) in list.withIndex()){
println("第${index}个元素是 $str")
}
kotlin 集合操作符
val list =arrayListOf<Char>{'a','b','c'}
val a = list.map {it - 'a'}
.filter {it > 0}
.find {it > 1}
fun main(args:Array<String>){
val a : Array<String> = arrayOf("4","0","h","d")
val index : Array<String> = arrayOf(0,4,5,7,8,3,6)
index.filter{
it < a.size
}.map{
a[it]
}.reduce{s,s1 ->
"$s$s1"
}.also{
println("$it")
}
}
kotlin 自定义集合操作符
其实kotlin 的所有操作符,都是以inline (内联函数)的扩展函数来实现的。例如下
inline fun <T,E> Iterable<T>.convert(action:(T) -> (E)):Iterable<E>{
val list:MutableList<E> =mutableListOf()
for(item:T in this) list.add(action(item))
return list
}
fun myQeperator(){
val list: List<Int> =listOf(1,2,3,4,5)
list.convert{
it+1
}.forEach{
println(it)
}
}
作用域函数
是kotlin 内置的一系列可以对数据做一个变换的函数。与集合的操作符相似,但集合的操作符只能用于集合的一系列数据变换。而作用域函数可以应用与所有对象,他可以对所有对象做一系列的操作
run{...}
with(T){...}
let{...}
apply{...}
also{...}
object Test {
@JvmStatic
fun main(){
val user=User("xiaoming")
var letResult:String =user.let { user: User -> "let::${user.javaClass}" }
println(letResult)
val runResult:String = user.run { "run: ${this.javaClass}" }
println(runResult)
user.also {
println("also :: ${it.javaClass}")
}
user.apply {
println("applu :: ${this.javaClass}")
}
user.takeIf {
it.name.length>0
}?.also {
println("takeIf name:: ${user.name}")
}?: println("takeIf 姓名为空")
user.takeUnless {
it.name.length>0
}?.also {
println("takeUnless 姓名为空")
}?: println("takeUnless 姓名为: ${user.name}")
with(user){
this.name="with"
}
}
}
data class User(var name:String)
kotlin 集合常用的操作符
元素操作类 contain – 判断是否有指定元素 elementAt – 返回对应的元素,越界会抛出IndexOutOfBoundsExceotion firstOrNull – 返回符合条件的第一个元素,没有返回null lastOrNull – 返回符合条件的第一个元素,没有返回null indexOf – 返回指定元素的下表,没有返回-1 singleOrNull – 返回符合条件的单个元素,如果没有符合或超过一个,返回null
判断类 any – 判断集合中是否有满足条件的元素 all – 判断集合中的元素是否都满足条件 none – 判断集合中是否都不满足条件,是则返回true count – 查询集合中满足条件的元素个数 reduce – 从第一项到最后一项进行累计
过滤类 filter – 过滤掉所有满足条件的元素 filterNot – 过滤所有不满足条件的元素 filterNotNull – 过滤所有不满足条件的元素 take – 返回前n个元素
转换类 map – 转换成另一个集合(与上面我们实现的convert 方法作用一样) mapIndexed – 除了转换成另一个集合,还可以拿到Index (下标) mapNotNull – 执行转换前过滤掉为NUll 的元素 flatMap – 自定义逻辑合并梨啊个集合 groupBy – 按照某个条件分组,返回Map
排序类 reversed – 反序 sorted – 升序 sortedBy – 自定义排序 sortedDescending – 降序
运算符重载 & 中缀表达式
在kotlin 中非常多的运算符都是通过重载来完成的
fun main(args:Array<String>){
for(i in 1..100 step 20){
println("$i ")
}
}
override fun iterator():IntIterator =IntProgressionIterator(first,last,setp)
internal class IntProgressionIterator(first:Int,last:Int,val step:Int):IntIterator{
private var next = first
private val finalElement = last
private var hasNext:Boolen =if(setp>0) first <=last else first >= last
override fun hasNext():Boolen = hasNext
override fun nextInt() : Int{
val value = next
if(value == finalElement){
hasNext = false
}else{
next += step
}
return value
}
}
运算符重载 和 中缀表达式本质上都是一个特殊的函数,都是通过函数的调用完成的
运算符的重载是有一个特点的。它一定是提前在kotlin 中定义的,不能凭空重载一个运算符。运算符是有上限的。当运算符不够的时候,我们需要通过中缀表达式扩展
中缀表达式
infix fun Int.vs(num:Int):CompareResult =
if(this - num < 0){
CompareResult.MORE
}else if(this - num > 0){
CompareResult.LESS
}else {
CompareResult.EQUAL
}
一个函数只有用于两个角色类型的对象时才将其声明为中缀函数 推荐示例:and 、to 、zip 、vs 反例:add 如果一个方法会改动其接收者,那么不要声明为中缀形式
kotlin 中的特殊符号
反引号
反引号作用: 1.可以用来解决关键字冲突问题 2.将一个不合法的字符串变成合法的 (例如下)
使用`` 便可合法化
fun `1234`(){}
fun `` (){}
fun ` `(){}
fun main(args:Array<String>){
`1234`()
` `()
` `()
}
该特性一般不会使用。除非这个类不希望被java 访问到时,
kotlin 中如何比较对象
a == b 比较值 <==> a.equals(b)
a === b 比较对象 <==> a == b
类型链接
public typealias A = File
fun main(args:Array<String>){
val a:File=A("")
}
public typealias HasMap<K,V> = java.util.HasMap<K,V>
DSL (Domain Specific Language-- 领域专用语言)
DSL 分为外部DSL 、和内部DSL
外部DSL(不依赖与其他的编程语言或自然语言)
内部DSL(本省还会依赖于其他编程语言)
- Anko kotlin 官方提供,通过DSL风格将安卓布局通过代码实现
- Kolley
- build.gradle
DSL优点 提高开发效率 减少沟通成本
DSL缺点 很难设计一个通用的DSL
|