Foreword |
|
xi | |
Acknowledgments |
|
xiii | |
Introduction |
|
xv | |
|
|
1 | (18) |
|
|
3 | (3) |
|
Why Should You Choose Kotlin? |
|
|
6 | (1) |
|
|
7 | (1) |
|
Compile to Bytecode and Run |
|
|
8 | (5) |
|
Compiling to Other Targets |
|
|
13 | (1) |
|
|
14 | (1) |
|
|
14 | (5) |
|
Part I Scripting with Kotlin |
|
|
|
2 Kotlin Essentials for the Java Eyes |
|
|
19 | (18) |
|
|
20 | (4) |
|
|
24 | (2) |
|
|
26 | (2) |
|
|
28 | (1) |
|
|
29 | (1) |
|
|
30 | (3) |
|
More Expressions, Fewer Statements |
|
|
33 | (2) |
|
|
35 | (2) |
|
|
37 | (16) |
|
|
38 | (5) |
|
Default and Named Arguments |
|
|
43 | (3) |
|
|
46 | (3) |
|
|
49 | (2) |
|
|
51 | (2) |
|
4 External Iteration and Argument Matching |
|
|
53 | (10) |
|
|
54 | (3) |
|
Iterating over Arrays and Lists |
|
|
57 | (1) |
|
When It's Time to Use when |
|
|
58 | (4) |
|
|
62 | (1) |
|
|
63 | (14) |
|
|
63 | (3) |
|
|
66 | (2) |
|
Arrays of Objects and Primitives |
|
|
68 | (2) |
|
|
70 | (2) |
|
|
72 | (1) |
|
|
73 | (2) |
|
|
75 | (2) |
|
6 Type Safety to Save the Day |
|
|
77 | (30) |
|
|
78 | (2) |
|
|
80 | (7) |
|
Type Checking and Casting |
|
|
87 | (4) |
|
|
91 | (2) |
|
Generics: Variance and Constraints of Parametric Types |
|
|
93 | (8) |
|
|
101 | (3) |
|
|
104 | (3) |
|
Part II Object-Oriented Kotlin |
|
|
|
|
107 | (26) |
|
|
107 | (6) |
|
|
113 | (11) |
|
Companion Objects and Class Members |
|
|
124 | (3) |
|
Creating Generics Classes |
|
|
127 | (2) |
|
|
129 | (3) |
|
|
132 | (1) |
|
8 Class Hierarchies and Inheritance |
|
|
133 | (16) |
|
Creating Interfaces and Abstract Classes |
|
|
134 | (4) |
|
|
138 | (2) |
|
|
140 | (4) |
|
|
144 | (1) |
|
|
145 | (3) |
|
|
148 | (1) |
|
9 Extension Through Delegation |
|
|
149 | (26) |
|
When to Choose Delegation over Inheritance? |
|
|
150 | (1) |
|
|
151 | (5) |
|
Delegating to a Parameter |
|
|
156 | (1) |
|
Dealing with Method Collisions |
|
|
157 | (3) |
|
Caveats of Kotlin Delegation |
|
|
160 | (2) |
|
Delegating Variables and Properties |
|
|
162 | (4) |
|
Built-in Standard Delegates |
|
|
166 | (4) |
|
|
170 | (5) |
|
Part III Functional Kotlin |
|
|
|
10 Functional Programming with Lambdas |
|
|
175 | (28) |
|
|
176 | (3) |
|
|
179 | (7) |
|
Lambdas and Anonymous Functions |
|
|
186 | (2) |
|
Closures and Lexical Scoping |
|
|
188 | (2) |
|
Non-Local and Labeled return |
|
|
190 | (4) |
|
Mining Functions with Lambdas |
|
|
194 | (7) |
|
|
201 | (2) |
|
11 Internal Iteration and Lazy Evaluation |
|
|
203 | (18) |
|
External vs. Internal Iterators |
|
|
204 | (2) |
|
|
206 | (7) |
|
Sequences for Lazy Evaluation |
|
|
213 | (5) |
|
|
218 | (3) |
|
Part IV Elegant and Efficient Kotlin |
|
|
|
|
221 | (28) |
|
|
222 | (4) |
|
Injecting Using Extension Functions and Properties |
|
|
226 | (8) |
|
|
234 | (1) |
|
Function Fluency with infix |
|
|
235 | (1) |
|
|
236 | (7) |
|
|
243 | (4) |
|
|
247 | (2) |
|
13 Creating Internal DSLs |
|
|
249 | (20) |
|
Types and Characteristics of DSLs |
|
|
250 | (1) |
|
|
251 | (3) |
|
Challenges in Building for Fluency |
|
|
254 | (6) |
|
|
260 | (5) |
|
Narrowing Access with Scope Control |
|
|
265 | (3) |
|
|
268 | (1) |
|
14 Programming Recursion and Memoization |
|
|
269 | (16) |
|
The Power and Perils of Recursion |
|
|
269 | (2) |
|
|
271 | (3) |
|
|
274 | (5) |
|
Applying Memoization to Dynamic Programming |
|
|
279 | (2) |
|
|
281 | (4) |
|
Part V Programming Asynchronous Applications |
|
|
|
|
285 | (24) |
|
Coroutines and Concurrency |
|
|
285 | (2) |
|
Running Concurrently Using Coroutines |
|
|
287 | (6) |
|
Coroutine Context and Threads |
|
|
293 | (5) |
|
|
298 | (2) |
|
|
300 | (1) |
|
|
301 | (2) |
|
Creating Infinite Sequences |
|
|
303 | (4) |
|
|
307 | (2) |
|
16 Asynchronous Programming |
|
|
309 | (20) |
|
Programming Asynchronously |
|
|
309 | (5) |
|
|
314 | (4) |
|
Cancellations and Timeouts |
|
|
318 | (8) |
|
|
326 | (3) |
|
Part VI Interop and Testing |
|
|
|
17 Intermixing Java and Kotlin |
|
|
329 | (18) |
|
|
330 | (3) |
|
|
333 | (3) |
|
|
336 | (10) |
|
|
346 | (1) |
|
18 Unit Testing with Kotlin |
|
|
347 | (28) |
|
|
348 | (1) |
|
Getting the Project Files |
|
|
349 | (3) |
|
Starting with a Canary Test |
|
|
352 | (1) |
|
|
353 | (3) |
|
Writing Data-Driven Tests |
|
|
356 | (1) |
|
|
357 | (6) |
|
Testing Top-Level Functions |
|
|
363 | (3) |
|
Testing Coroutines and Asynchronous Calls |
|
|
366 | (4) |
|
Integrating with the Service |
|
|
370 | (1) |
|
Viewing the Code Coverage |
|
|
371 | (1) |
|
Taking the App for a Drive |
|
|
372 | (1) |
|
|
373 | (2) |
|
19 Programming Spring Applications with Kotlin |
|
|
375 | (12) |
|
Creating a Starter Project |
|
|
376 | (2) |
|
|
378 | (2) |
|
|
380 | (1) |
|
Creating a Repository Interface |
|
|
381 | (1) |
|
|
381 | (2) |
|
Integrating the Service with Controller |
|
|
383 | (2) |
|
|
385 | (1) |
|
|
386 | (1) |
|
20 Writing Android Applications with Kotlin |
|
|
387 | (18) |
|
|
388 | (2) |
|
|
390 | (1) |
|
|
391 | (4) |
|
Implementing the Activity |
|
|
395 | (4) |
|
Updating the RecyclerView |
|
|
399 | (2) |
|
|
401 | (1) |
|
|
402 | (3) |
A1 Transpiring to JavaScript |
|
405 | (4) |
A2 Kotlin/Native |
|
409 | (4) |
A3 Kotlin to WebAssembly |
|
413 | (4) |
Bibliography |
|
417 | (2) |
Index |
|
419 | |