/**
* 泛型:泛指任意类型
* 修饰函数:泛型函数
* 类:泛型类
*/
/**
* 使用out修饰的集合,只能接受指定类型的子类组成的集合
* out修饰的集合对象,只能取,不能存
* 型变
*/
/**
* 使用in修饰的集合,只能接受指定类型的父类类组成的集合
* in修饰的集合对象,只能存,不能取
*/
/**
* 修饰类:
* out:指定的类型只能作为返回值来获取
* in:指定的类型只能通过函数的参数传递进来
*/
// 1 2 3 4
//如果有把索引和元素返回
//如果没有返回-1和null
fun Array.findElement(element:T, func:(Int,T?) -> Unit){//Array的拓展函数findElement(这是个高阶函数)
for (i in this.indices){//如果该数组中有和要找的元素一样的元素
if (this[i] == element){//执行函数func,参数是i和element
func(i,element)
return
}
}
//没有
func(-1,null)//执行函数func 参数是-1和null
}
fun test(){
val array1 =arrayOf(1,2,3,4,5,6)
val array2 =arrayOf("Jack","Rose","Marry")
array2.findElement("Jack"){ index, value-> //lambda表达式的参数名称
println("$index$value") //lambda表达式要执行的语句
}
}
class MyArray{
var contents =arrayListOf()
fun get(index:Int):T?{
if (indexin 0 until contents.size){
return contents[index]
}else{
return null
}
}
fun add(e:T){
contents.add(e)
}
}
open class Old
open class Father:Old()
class Child:Father()
fun main() {
var childList:List =listOf()
var fatherList:List =listOf(Child())
val childArrayList:ArrayList =arrayListOf()
val fatherArrayList:ArrayList = childArrayList
//out:只能放置子类类型
//in:只能放置父类类型
}
class Person{
var name:String =""
var age:Int =0
var weight:Float =0f
}
fun main() {
val pp = Person()
//正常访问方式
pp.name ="Jack"
pp.age =30
pp.weight =150f
//inline 内存资源 函数的参数是一个Lambda
//查看also、apply、with、run、let的实现方式
//let -> ?.let
/**
* 使用it引用外部对象
* 返回值为 闭包/Lambda内部最后一行的结果
*/
val result = pp.let {
it.name ="Jack"
it.age =30
it.weight =150f
12
}
/**
* ?.let 判断是否为空
*/
val p:Person? =null
p?.let {
//.....安全
}
/**
* also
* 当创建一个对象后,需要对这个对象进行额外操作
* 返回值就是这个对象本身
*/
//also -> object.also{}
val p2 = Person().also {
it.name ="Jack"
it.age =18
it.weight =150f
println(it)
}
//apply -> object.apply()
/**
* apply
* 当创建一个对象之后 需要对这个对象进行初始化
* 闭包内部使用this来引用对象本身
* 返回值就是对象本身
*/
Person().apply {
name ="Jack"
age =8
weight =150f
}
}
/**
* 协程Coroutline
*
* 进程:正在运行的程序
* 线程:真正完成任务的单元、
*
*
* 线程的分配:操作系统为线程分配所需的内存资源
* 线程分配过多会导致内存溢出
* OOM Out Of Memory
* 多线程:多个线程,执行多个任务
* 同步:A -> B -> C
* 异步:同时执行多个任务,CPU
* 同一时间,一个cpu只能执行一件事情,时间片分配
*
* 协程:轻量级的线程 JVM级别 几乎不耗任何资源
*
* Android中子线程不能操作UI 只能处理非UI的事物
*/
/**
* Job
* 记录当前协程运行状态(isActive isComplete isCancel)
* start
* cancel
* resume
* join:等这个协程执行完毕
*
* launch和async开启任务的区别
* 不会阻塞当前线程
* launch返回的是Job
* async返回的是Deffered<T>:Job T为操作之后得到的数据,使用await获取
*/
fun main()=runBlocking{
println("start ${Thread.currentThread().name}")
val job =launch {
val t =measureTimeMillis {
task1()
task2()
}
println(t)
}
val data1 =async {
//A
"www.baidu.com/image/1.jpg"
}
val url = data1.await()
async {
//B
println("开始下载 $url")
//
"1.jpg"
}
val scope =CoroutineScope(job + Dispatchers.Main)
scope.launch {
///
}
launch {
task2()
}
println("end ${Thread.currentThread().name}")
}
suspend fun task1(){
delay(2000)
}
suspend fun task2(){
delay(3000)
}
/**
* suspend
* 用于修饰函数,表示这个功能会阻塞主线程,挂起函数
* 挂起函数的调用只能在另外一个挂起函数或者协程中调用
* 不能在主线程中直接调用
*/
/**
* 如何开启一个协程
* CoroutineScope 协程域 有了这个,挂起函数才能执行,同一个域里面可以开启多个协程
* runBlocking 测试
* 默认会在当前线程上执行
*/
/**
* 如何切换协程运行环境
* withContext()
* Dispatchers
* IO
* Default
* Main
* Unconfined
*/
suspend fun download(){
withContext(Dispatchers.IO){
println("C1 start ${Thread.currentThread().name}")
delay(1000)
println("C1 end ${Thread.currentThread().name}")
withContext(Dispatchers.Main){
//更新UI
}
}
}
/**
* 网络获取数据:Json -> 对象 -> 操作
* NewsModel
* val total:Int
* val data:List<>
* News
* val uid:Int
* val title:String
* val time:Date
*
* Map("title":"广东夺冠了","pic":"易建联笑哈哈.jpg")
* Pairs
*/
fun main() {
val data =downloadData()
val obj =autoCreateInstance(data,Good::class)
}
fun autoCreateInstance(
data:Map>,
clz:KClass
):Any?{
//获取这个类对应的数据
val result = data[clz.simpleName]
//获取主构造函数
val pconstr = clz.primaryConstructor
//获取主构造函数的参数
val valuesParameterArray =arrayOfNulls((pconstr?.parameters?.size)!!)
pconstr?.parameters.also {
it?.forEach {parameter->
//获取参数的名字
val name = parameter.name!!
val value = result?.get(name)
valuesParameterArray[parameter.index] = value
}
}
//创建对象
return pconstr?.call(*valuesParameterArray)
}
fun downloadData():Map> {
/**
* key-value 键值对
*/
val news =mapOf(
Pair("title","广东夺冠了"),
Pair("pic","易建联笑哈哈.jpg")
)
val goods =mapOf(
Pair("name","防晒霜"),
Pair("price","500"),
Pair("num","100")
)
val results =mapOf(
"News" to news,
"Good" to goods
)
return results
}
data class News(val title:String,val Pic:String)
data class Good(val name:String,val price:String,val num:String)
/**
* 异常处理 简单且重要
* try - 具体可能出现bug的代码
* catch - 捕获可能的异常
* finally - 最终都会执行的代码
*
*
* 异常的类Exception
*/
自己定义一个异常类
以下是灵活写法
class SomethingHappenException(message:String): Exception(message){
}
fun main() {
if (2 >1){
throw SomethingHappenException("自己写的某些异常信息...")
}
写死了:
class SomethingHappenException(): Exception("自己写的某些异常信息..."){
}
fun main() {
if (2 >1){
throw SomethingHappenException()
}
try {
val num =readLine()?.toInt()
println(num)
}catch (e:Exception){
println("捕获异常了:${e.message}")
}finally {
println("处理结果")
}
}
意义:纵使bug发生,程序也可以继续运行下去
小技巧:如果在catch时不知道具体是什么异常,没有学过,就写这个异常的父类,Exception,里面就囊括了所有异常的类型
StackTrace:跟踪所有执行的方法 会把所有已经执行的方法、在哪一步出错这些信息打印出来
message:程序不会崩溃 而是得到了具体的异常(比StackTrace更加精准)
异常出现了就不执行try接下来的语句 而是直接调到catch部分