Android面试题:App性能优化之Java和Kotlin常见的数据结构

简介: Java数据结构摘要:ArrayList基于数组,适合查找和修改;LinkedList适合插入删除;HashMap1.8后用数组+链表/红黑树,初始化时预估容量可避免扩容。SparseArray优化查找,ArrayMap减少冲突。Kotlin优化摘要:Kotlin的List用`listOf/mutableListOf`,Map用`mapOf/mutableMapOf`,支持操作符重载和扩展函数。序列提供懒加载,解构用于遍历Map,扩展函数默认参数增强灵活性。

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点

Java常见数据结构特点

ArrayList

  • ArrayList底层是基于数组实现
  • add、删除元素需要进行元素位移耗性能,但查找和修改块
  • 适合不需要频繁添加删除的

链表

  • LinkedList 是双链表插入和删除节点快,查找和修改耗时

HashMap

  • 1.7之前是数组+链表;1.8之后是数组+链表+红黑树
  • 计算key的位置时用的位运算:h & (length-1),位运算更快
  • HashMap对应的key、value是一一对应的唯一的
扩容
  • 默认HashMap大小是16,必须是2的倍数
  • 加载因子:默认是0.75
  • 阈值:0.75 * 16 = 12的时候扩容
  • 扩容是为了避免冲突,提升性能,扩容的时候会重新计算哈希,比较耗性能
  • 要尽量避免扩容,初始化的时候要设置HashMap的大小,会自动计算到最接近的2的次幂
  • HashMap真正初始化的时候是在put的时候,节约内存
  • 为什么是2的次幂,是为了计算index:h & (length-1),后面是1111,计算index更不容易碰撞
  • HashMap是用空间换时间

HashMap的一个经典的优化就是初始化时,尽可能的设置要初始化的容量,尽量避免扩容的发生

SparseArray

  • 原理是2个数组,key一个数组,value一个数组,key和value一一对应
  • key是int,value是object
  • key数组是按照大小顺序排,查找的时候是2分查找,提升性能
  • remove的时候,不会真的移除,而是会做个标记,这样不用arraycopy,下次再put就是一个赋值操作,提升性能
  • 会越用越快,缺点是key只能是int

ArrayMap

  • 原理是HashMap+SparseArray,也是2个数组,key数组和value数组,不过key不限于int
  • key的计算和HashMap一样,不过有哈希冲突时,没有用链表而是追加到后面

Kotlin中的优化

Kotlin提供了一些优化和特性来简化和高效地操作常见的数据结构,如 ListMap。以下是一些针对这些数据结构的优化和特性示例:

List

  1. Immutable Lists: 使用 listOf() 创建不可变列表。
  2. Mutable Lists: 使用 mutableListOf() 创建可变列表。
  3. 操作符重载: 你可以使用标准库中的高阶函数、扩展函数和操作符重载来高效地操作列表。
// 创建不可变列表
val numbers: List<Int> = listOf(1, 2, 3, 4, 5)

// 创建可变列表
val mutableNumbers: MutableList<Int> = mutableListOf(1, 2, 3)
mutableNumbers.add(4)

// 使用扩展函数
val doubled = numbers.map { it * 2 }  // [2, 4, 6, 8, 10]
val filtered = numbers.filter { it > 2 }  // [3, 4, 5]

Map

  1. Immutable Maps: 使用 mapOf() 创建不可变映射。
  2. Mutable Maps: 使用 mutableMapOf() 创建可变映射。
  3. Destructuring: 优化遍历和解构键值对。
// 创建不可变映射
val map: Map<String, Int> = mapOf("a" to 1, "b" to 2, "c" to 3)

// 创建可变映射
val mutableMap: MutableMap<String, Int> = mutableMapOf("x" to 10, "y" to 20)
mutableMap["z"] = 30

// 使用扩展函数
val keys = map.keys  // 获取所有的键
val values = map.values  // 获取所有的值

// Destructuring
for ((key, value) in map) {
    println("Key: $key, Value: $value")
}

特定优化和高级功能

1、Kotlin的序列提供了懒加载特性,有助于处理大量数据。
2、在扩展函数中使用默认参数提高代码可读性和灵活性。

// Lazy Sequence
val lazyList = listOf(1, 2, 3, 4, 5).asSequence()
    .filter { it % 2 == 0 }
    .map { it * 2 }
    .toList()

// 使用默认参数的扩展函数
fun List<Int>.sum(defaultValue: Int = 0): Int {
    return this.fold(defaultValue) { acc, i -> acc + i }
}

val sum = listOf(1, 2, 3).sum()  // 默认参数,结果是6
val sumWithInitial = listOf(1, 2, 3).sum(10)  // 初始值为10,结果是16

通过这些优化和特性,Kotlin使得操作常见数据结构变得更加简洁和高效。同时,通过深入使用Kotlin标准库中的扩展函数和特性,我们也可以大大简化代码并提高其可读性和可维护性。


欢迎关注我的公众号AntDream查看更多精彩文章!

目录
相关文章
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
1649 4
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
503 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
网络协议 Linux Android开发
深入探索Android系统架构与性能优化
本文旨在为读者提供一个全面的视角,以理解Android系统的架构及其关键组件。我们将探讨Android的发展历程、核心特性以及如何通过有效的策略来提升应用的性能和用户体验。本文不包含常规的技术细节,而是聚焦于系统架构层面的深入分析,以及针对开发者的实际优化建议。
525 21
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
455 4
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
344 5
|
缓存 数据库 Android开发
安卓开发中的性能优化技巧
【10月更文挑战第29天】在移动应用的海洋中,性能是船只能否破浪前行的关键。本文将深入探讨安卓开发中的性能优化策略,从代码层面到系统层面,揭示如何让应用运行得更快、更流畅。我们将以实际案例和最佳实践为灯塔,引领开发者避开性能瓶颈的暗礁。
429 3