网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
请看下面这个方法:
fun Any.ofMap() =
// 过滤掉除data class以外的其他类
this::class.takeIf { it.isData }
// 遍历类的所有成员 过滤掉成员方法 只考虑成员属性
?.members?.filterIsInstance<KProperty<Any>>()
// 将成员属性名和值存储在Pair中
?.map { it.name to it.call(this) }
// 将Pair转换成map
?.toMap()
为任意 Kotlin 中的类添加一个扩展函数
,它的功能是将data class
中所有的字段名及其对应值存在一个 map 中。其中用到的 Kotlin 语法糖如下:
isData
是KClass
中的一个属性,用于判断该类是不是一个data class
。KClass
是 Kotlin 中用来描述 类的类型,KClass
可以通过对象::class
语法获得。members
也是KClass
中的一个属性,它以列表的形式返回了类中所有的方法和属性。filterIsInstance()
是Iterable
接口的扩展函数,用于过滤出集合中指定的类型。to
是一个infix
扩展函数,它的定义如下:
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
- 带有
infix
标识的函数只允许带有一个参数,并且在调用时可以省略包裹参数的括号。这种语法叫中缀表达式
,它用于简化方法调用。
写段测试代码,结合上一节的打印 map 函数看下效果:
data class Person(var name: String, var age: Int)
Person("Peter", 16).ofMap()?.print { it.toString() }.let { Log.v("test","$it") }
测试代码先将Person
实例转换成 map,然后打印 map。输出结果如下:
V/test:
{
[age] = 16
[name] = Peter
}
若data class
嵌套会发生什么?
//位置,嵌套在Person类中
data class Location(var x: Int, var y: Int)
data class Person(
var name: String,
var age: Int,
var locaton: Location? = null
)
Person("Peter", 16, Location(20, 30))
.ofMap()
?.print { it.toString() }
.let { Log.v("test", "$it") }
// 打印结果如下
{
[age] = 16
[locaton] = Location(x=20, y=30)
[name] = Peter
}
期望得到类似 Json 的打印效果,但输出结果还差一点。是因为将Person
转化成Map
时并没有将嵌套的Location
也转化成键值对。
需要将ofMap()
方法重构成递归调用:
fun Any.ofMap(): Map<String, Any?>? {
return this::class.takeIf { it.isData }
?.members?.filterIsInstance<KProperty<Any>>()
?.map { member ->
val value = member.call(this)?.let { v->
//'若成员变量是data class,则递归调用ofMap(),将其转化成键值对,否则直接返回值'
if (v::class.isData) v.ofMap()
else v
}
member.name to value
}
?.toMap()
}
为了让打印结果也有嵌套缩进效果,打印 Map 的函数也需要相应地重构:
/**
* 打印 Map,生成结构化键值对子串
* @param space 行缩进量
*/
fun <K, V> Map<K, V?>.print(space: Int = 0): String {
//'生成当前层次的行缩进,用space个空格表示,当前层次每一行内容都需要带上缩进'
val indent = StringBuilder().apply {
repeat(space) { append(" ") }
}.toString()
return StringBuilder("\n${indent}{").also { sb ->
this.iterator().forEach { entry ->
//'如果值是 Map 类型,则递归调用print()生成其结构化键值对子串,否则返回值本身'
val value = entry.value.let { v ->
(v as? Map<*, *>)?.print("${indent}${entry.key} = ".length) ?: v.toString()
}
sb.append("\n\t${indent}[${entry.key}] = $value,")
}
sb.append("\n${indent}}")
}.toString()
}
写段测试代码,看看效果:
//'坐标类,嵌套在Location类中'
data class Coordinate(var x: Int, var y: Int)
//'位置类,嵌套在Person类中'
data class Location(
var country: String,
var city: String,
var coordinate: Coordinate
)
data class Person(
var name: String,
var age: Int,
var locaton: Location? = null
)
Person("Peter", 16, Location("china", "shanghai", Coordinate(10, 20)))
.ofMap()
?.print()
.let { Log.v("test", "$it") }
//'打印效果如下'
{
[age] = 16,
[locaton] =
{
[city] = shanghai,
[coordinate] =
{
[x] = 10,
[y] = 20,
},
[country] = china,
},
[name] = Peter,
}
推荐阅读
作者:唐子玄
链接:https://juejin.cn/post/7171031370511155231
最后
如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
一、架构师筑基必备技能
1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……
二、Android百大框架源码解析
1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程
三、Android性能优化实战解析
- 腾讯Bugly:对字符串匹配算法的一点理解
- 爱奇艺:安卓APP崩溃捕获方案——xCrash
- 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
- 百度APP技术:Android H5首屏优化实践
- 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
- 携程:从智行 Android 项目看组件化架构实践
- 网易新闻构建优化:如何让你的构建速度“势如闪电”?
- …
四、高级kotlin强化实战
1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》
- 从一个膜拜大神的 Demo 开始
- Kotlin 写 Gradle 脚本是一种什么体验?
- Kotlin 编程的三重境界
- Kotlin 高阶函数
- Kotlin 泛型
- Kotlin 扩展
- Kotlin 委托
- 协程“不为人知”的调试技巧
- 图解协程:suspend
五、Android高级UI开源框架进阶解密
1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南
六、NDK模块开发
1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习
七、Flutter技术进阶
1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
-blog.csdnimg.cn/direct/743b668910224b259a5ffe804fa6d0db.png)
[外链图片转存中…(img-srGYYkX1-1715637278242)]
[外链图片转存中…(img-I9iGp5iB-1715637278242)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新