1. 准备工作
在此开发者在线课程中,您学习了泛型、不同类型的类、集合以及高阶函数。为了练习所学的内容,您将帮助所在团队改进新的活动跟踪应用。每个步骤的说明都会描述应用的当前状态以及您应该完成的任务。
建议使用 Kotlin 园地来解答这些练习。
前提条件
- 完成 Android 之 Compose 开发基础课程的第 3 单元在线课程 1 及其之前的在线课程。
- 熟悉 Kotlin 编程语言的基础知识,包括类、对象、集合和高阶函数。
所需条件
- 一台可连接互联网的计算机
- 能够访问 Kotlin 园地
2. 应用概览
您是新加入活动跟踪应用团队的软件工程师。该应用旨在让用户能够跟踪他们的活动。您的任务是帮助构建应用的功能。
每个任务结束时,您应将您的解决方案与所提供的解决方案进行比较。实现所需功能的方式有很多种,因此如果您的代码与所提供的解决方案代码不完全一致,大可不必担心。
使用上一个任务中提供的解决方案代码作为下一个任务的起始代码,以便从共同的起点开始。
3. 任务 1
另一位软件工程师已经完成了该应用的一些主体工作,您将负责实现细节部分。
您需要实现 Event
类。此类用于存储用户输入的活动详细信息。(提示:此类不需要定义任何方法或执行任何操作。)
对于此任务,您需要创建一个名为 Event
的数据类。
此类的实例应该能够存储:
- 活动标题(以字符串表示)。
- 活动说明(以字符串表示,可以为 null)。
- 活动时段(以字符串表示)。我们只需跟踪活动在上午、下午还是晚上开始。
- 活动时长(分钟,以整数表示)。
在继续操作之前,请尝试自行编写代码。
使用您的代码,根据以下信息创建实例:
- 标题:学习 Kotlin
- 说明:坚持每天至少学习 Kotlin 15 分钟。
- 时段:晚上
- 时长:15
请尝试输出对象以验证您是否获得了以下输出:
Event(title=Study Kotlin, description=Commit to studying Kotlin at least 15 minutes per day., daypart=Evening, durationInMinutes=15)
完成该任务或尽最大努力尝试该任务后,点击 Next 即可查看我们编写的代码。
4. 任务 1 解决方案
您的解决方案应类似于以下代码:
data class Event(
val title: String,
val description: String? = null,
val daypart: String,
val durationInMinutes: Int,
)
5. 任务 2
为确保项目顺利进行,您的经理决定使用我们为数据类提供的代码。
整个团队使用 Event
类一段时间后,资深的团队成员意识到使用字符串表示时段效果并不理想。
一些开发者存储了“Morning”值,还有一些使用了“morning”,另一些开发者使用了“MORNING”。
这会导致许多问题。
您的任务就是通过进行一些重构来解决此问题。重构是改进代码而不改变其功能的过程。一些示例包括简化逻辑或将重复代码移到单独的函数中。
哪种类型的类可用于对一组有限的不同值进行建模,以帮助纠正此问题?
您的团队希望您将时段代码更改为使用枚举类。使用枚举类时,您的同事不得不选择所提供的时段值之一,这可以防止出现此类问题。
枚举类应命名为 Daypart
。它应该有三个值:
MORNING
AFTERNOON
EVENING
您将如何创建此枚举类?
您如何重构 Event
类以使用它?
请尝试立即编写解决方案代码,然后再继续。
点击 Next 即可查看我们编写的代码。
6. 任务 2 解决方案
enum class Daypart {
MORNING,
AFTERNOON,
EVENING,
}
重构后的 Event
数据类现在使用枚举类:
data class Event(
val title: String,
val description: String? = null,
val daypart: Daypart,
val durationInMinutes: Int,
)
7. 任务 3
您的同事喜欢使用重构后的 Daypart
,但他们还会遇到其他问题。
以下代码展示了他们当前如何创建和存储用户的活动。
val event1 = Event(title = "Wake up", description = "Time to get up", daypart = Daypart.MORNING, durationInMinutes = 0)
val event2 = Event(title = "Eat breakfast", daypart = Daypart.MORNING, durationInMinutes = 15)
val event3 = Event(title = "Learn about Kotlin", daypart = Daypart.AFTERNOON, durationInMinutes = 30)
val event4 = Event(title = "Practice Compose", daypart = Daypart.AFTERNOON, durationInMinutes = 60)
val event5 = Event(title = "Watch latest DevBytes video", daypart = Daypart.AFTERNOON, durationInMinutes = 10)
val event6 = Event(title = "Check out latest Android Jetpack library", daypart = Daypart.EVENING, durationInMinutes = 45)
他们创建了许多活动,目前每个活动都需要有自己的变量。随着创建的活动越来越多,跟踪这些活动变得更加困难。使用这种方法时,确定用户安排的活动数量有多难?
您能想出更好的方法来整理这些活动的存储方式吗?
如何将所有活动存储在一个变量中?(注意:此方案必须灵活,因为可能会添加更多活动)。还需要能够高效地返回存储在变量中的活动数。)
您应使用哪种类或数据类型?可以通过哪种方法添加更多活动?
现在,您该实现此功能了。请先编写代码,然后点击 Next 查看我们的解决方案。
8. 任务 3 解决方案
val events = mutableListOf<Event>(event1, event2, event3, event4, event5, event6)
9. 任务 4
您的经理很喜欢该应用目前的进展,但决定应该基于活动的时长向用户显示其短期活动的摘要。例如,“您有 5 个短期活动。”
“短期”活动是指不到 60 分钟的活动。
使用上一个任务的解决方案中的 events
变量代码,您如何实现此结果?
点击 Next 继续查看我们的解决方案。
10. 任务 4 解决方案
可以通过多种方法实现此目的,我们决定使用如下方法:
val shortEvents = events.filter { it.durationInMinutes < 60 }
println("You have ${shortEvents.size} short events.")
11. 任务 5
您的同事很喜欢该应用目前的进展,但他们希望用户能够看到所有活动及其时段的摘要。
输出的内容应类似于以下文本:
Morning: 3 events Afternoon: 4 events Evening: 2 events
使用上一步中的 events
变量代码,您如何实现此效果?
点击 Next 查看解决方案代码。
12. 任务 5 解决方案
以下是我们的解决方案,但其他方案也可接受。
val groupedEvents = events.groupBy { it.daypart }
groupedEvents.forEach { (daypart, events) ->
println("$daypart: ${events.size} events")
}
13. 任务 6
目前,您的同事会通过索引查找并输出最后一项内容。所用的代码为:println("Last event of the day: ${events[events.size - 1].title}")
。
您的经理建议查看 Kotlin 文档,寻找可以简化此代码的函数。
您发现了什么函数?
请尝试使用该函数来确认输出的结果是否相同。
点击 Next 查看解决方案。
14. 任务 6 解决方案
println("Last event of the day: ${events.last().title}")
15. 任务 7
大家很喜欢您设计的数据类,但发现每次需要以字符串形式表示活动的时长时,都要重复编写代码:
val durationOfEvent = if (events[0].durationInMinutes < 60) {
"short"
} else {
"long"
}
println("Duration of first event of the day: $durationOfEvent")
虽然您可以通过直接向类添加方法来解决这种重复问题,但这并不理想,因为其他团队已开始在他们的应用中使用您的活动类。如果该类发生变化,他们需要重新测试所有代码,以确保您所做的更改不会造成任何中断。
如果不直接更改数据类,如何编写会返回与上述代码相同的值的扩展属性?
正确实现后,您将能够使用以下代码,它将输出与此任务开头所显示的代码相同的消息。
println("Duration of first event of the day: ${events[0].durationOfEvent}")
点击 Next 继续查看解决方案。
16. 任务 7 解决方案
val Event.durationOfEvent: String
get() = if (this.durationInMinutes < 60) {
"short"
} else {
"long"
}
17. 其他练习
如需尝试 Kotlin 语言的更多练习,请查看 JetBrains Academy 的 Kotlin Core 课程。如需跳转到特定主题,请前往知识图谱,查看上述课程涵盖的主题列表。