Preface |
|
xiii | |
1 Command-Line Tasks |
|
1 | (20) |
|
1.1 Getting Started with the Scala REPL |
|
|
3 | (3) |
|
1.2 Loading Source Code and JAR Files into the REPL |
|
|
6 | (2) |
|
1.3 Getting Started with the Ammonite REPL |
|
|
8 | (3) |
|
1.4 Compiling with scalac and Running with scala |
|
|
11 | (2) |
|
1.5 Disassembling and Decompiling Scala Code |
|
|
13 | (4) |
|
1.6 Running JAR Files with Scala and Java |
|
|
17 | (4) |
2 Strings |
|
21 | (32) |
|
2.1 Testing String Equality |
|
|
24 | (2) |
|
2.2 Creating Multiline Strings |
|
|
26 | (1) |
|
|
27 | (2) |
|
2.4 Substituting Variables into Strings |
|
|
29 | (3) |
|
2.5 Formatting String Output |
|
|
32 | (4) |
|
2.6 Processing a String One Character at a Time |
|
|
36 | (5) |
|
2.7 Finding Patterns in Strings |
|
|
41 | (2) |
|
2.8 Replacing Patterns in Strings |
|
|
43 | (1) |
|
2.9 Extracting Parts of a String That Match Patterns |
|
|
44 | (2) |
|
2.10 Accessing a Character in a String |
|
|
46 | (1) |
|
2.11 Creating Your Own String Interpolator |
|
|
47 | (3) |
|
2.12 Creating Random Strings |
|
|
50 | (3) |
3 Numbers and Dates |
|
53 | (32) |
|
3.1 Parsing a Number from a String |
|
|
56 | (3) |
|
3.2 Converting Between Numeric Types (Casting) |
|
|
59 | (3) |
|
3.3 Overriding the Default Numeric Type |
|
|
62 | (2) |
|
3.4 Replacements for ++ and -- |
|
|
64 | (1) |
|
3.5 Comparing Floating-Point Numbers |
|
|
65 | (2) |
|
3.6 Handling Large Numbers |
|
|
67 | (2) |
|
3.7 Generating Random Numbers |
|
|
69 | (2) |
|
3.8 Formatting Numbers and Currency |
|
|
71 | (5) |
|
3.9 Creating New Date and Time Instances |
|
|
76 | (2) |
|
3.10 Calculating the Difference Between Two Dates |
|
|
78 | (2) |
|
|
80 | (2) |
|
3.12 Parsing Strings into Dates |
|
|
82 | (3) |
4 Control Structures |
|
85 | (44) |
|
4.1 Looping over Data Structures with for |
|
|
88 | (4) |
|
4.2 Using for Loops with Multiple Counters |
|
|
92 | (1) |
|
4.3 Using a for Loop with Embedded if Statements (Guards) |
|
|
93 | (2) |
|
4.4 Creating a New Collection from an Existing Collection with for/yield |
|
|
95 | (2) |
|
4.5 Using the if Construct Like a Ternary Operator |
|
|
97 | (1) |
|
4.6 Using a Match Expression Like a switch Statement |
|
|
98 | (4) |
|
4.7 Matching Multiple Conditions with One Case Statement |
|
|
102 | (1) |
|
4.8 Assigning the Result of a Match Expression to a Variable |
|
|
103 | (1) |
|
4.9 Accessing the Value of the Default Case in a Match Expression |
|
|
104 | (1) |
|
4.10 Using Pattern Matching in Match Expressions |
|
|
105 | (6) |
|
4.11 Using Enums and Case Classes in match Expressions |
|
|
111 | (2) |
|
4.12 Adding if Expressions (Guards) to Case Statements |
|
|
113 | (2) |
|
4.13 Using a Match Expression Instead of isInstanceOf |
|
|
115 | (2) |
|
4.14 Working with a List in a Match Expression |
|
|
117 | (3) |
|
4.15 Matching One or More Exceptions with try/catch |
|
|
120 | (3) |
|
4.16 Declaring a Variable Before Using It in a try/catch/finally Block |
|
|
123 | (2) |
|
4.17 Creating Your Own Control Structures |
|
|
125 | (4) |
5 Classes |
|
129 | (50) |
|
5.1 Choosing from Domain Modeling Options |
|
|
131 | (6) |
|
5.2 Creating a Primary Constructor |
|
|
137 | (3) |
|
5.3 Controlling the Visibility of Constructor Fields |
|
|
140 | (4) |
|
5.4 Defining Auxiliary Constructors for Classes |
|
|
144 | (2) |
|
5.5 Defining a Private Primary Constructor |
|
|
146 | (2) |
|
5.6 Providing Default Values for Constructor Parameters |
|
|
148 | (1) |
|
5.7 Handling Constructor Parameters When Extending a Class |
|
|
149 | (3) |
|
5.8 Calling a Superclass Constructor |
|
|
152 | (2) |
|
5.9 Defining an equals Method (Object Equality) |
|
|
154 | (8) |
|
5.10 Preventing Accessor and Mutator Methods from Being Generated |
|
|
162 | (3) |
|
5.11 Overriding Default Accessors and Mutators |
|
|
165 | (2) |
|
5.12 Assigning a Block or Function to a (lazy) Field |
|
|
167 | (2) |
|
5.13 Setting Uninitialized var Field Types |
|
|
169 | (2) |
|
5.14 Generating Boilerplate Code with Case Classes |
|
|
171 | (5) |
|
5.15 Defining Auxiliary Constructors for Case Classes |
|
|
176 | (3) |
6 Traits and Enums |
|
179 | (38) |
|
6.1 Using a Trait as an Interface |
|
|
181 | (2) |
|
6.2 Defining Abstract Fields in Traits |
|
|
183 | (2) |
|
6.3 Using a Trait Like an Abstract Class |
|
|
185 | (1) |
|
6.4 Using Traits as Mixins |
|
|
186 | (3) |
|
6.5 Resolving Method Name Conflicts and Understanding super |
|
|
189 | (3) |
|
6.6 Marking Traits So They Can Only Be Used by Subclasses of a Certain Type |
|
|
192 | (4) |
|
6.7 Ensuring a Trait Can Only Be Added to a Type That Has a Specific Method |
|
|
196 | (1) |
|
6.8 Limiting Which Classes Can Use a Trait by Inheritance |
|
|
197 | (1) |
|
6.9 Working with Parameterized Traits |
|
|
198 | (2) |
|
6.10 Using Trait Parameters |
|
|
200 | (4) |
|
6.11 Using Traits to Create Modules |
|
|
204 | (6) |
|
6.12 How to Create Sets of Named Values with Enums |
|
|
210 | (3) |
|
6.13 Modeling Algebraic Data Types with Enums |
|
|
213 | (4) |
7 Objects |
|
217 | (16) |
|
|
218 | (1) |
|
7.2 Passing a Class Type with the classOf Method |
|
|
219 | (1) |
|
7.3 Creating Singletons with object |
|
|
220 | (1) |
|
7.4 Creating Static Members with Companion Objects |
|
|
221 | (2) |
|
7.5 Using apply Methods in Objects as Constructors |
|
|
223 | (2) |
|
7.6 Implementing a Static Factory with apply |
|
|
225 | (2) |
|
7.7 Reifying Traits as Objects |
|
|
227 | (3) |
|
7.8 Implementing Pattern Matching with unapply |
|
|
230 | (3) |
8 Methods |
|
233 | (22) |
|
8.1 Controlling Method Scope (Access Modifiers) |
|
|
235 | (4) |
|
8.2 Calling a Method on a Superclass or Trait |
|
|
239 | (3) |
|
8.3 Using Parameter Names When Calling a Method |
|
|
242 | (2) |
|
8.4 Setting Default Values for Method Parameters |
|
|
244 | (1) |
|
8.5 Creating Methods That Take Variable-Argument Fields |
|
|
245 | (2) |
|
8.6 Forcing Callers to Leave Parentheses Off Accessor Methods |
|
|
247 | (1) |
|
8.7 Declaring That a Method Can Throw an Exception |
|
|
248 | (2) |
|
8.8 Supporting a Fluent Style of Programming |
|
|
250 | (3) |
|
8.9 Adding New Methods to Closed Classes with Extension Methods |
|
|
253 | (2) |
9 Packaging and Imports |
|
255 | (16) |
|
9.1 Packaging with the Curly Braces Style Notation |
|
|
256 | (2) |
|
9.2 Importing One or More Members |
|
|
258 | (1) |
|
9.3 Renaming Members on Import |
|
|
259 | (2) |
|
9.4 Hiding a Class During the Import Process |
|
|
261 | (2) |
|
9.5 Importing Static Members |
|
|
263 | (1) |
|
9.6 Using Import Statements Anywhere |
|
|
264 | (3) |
|
|
267 | (4) |
10 Functional Programming |
|
271 | (46) |
|
10.1 Using Function Literals (Anonymous Functions) |
|
|
279 | (2) |
|
10.2 Passing Functions Around as Variables |
|
|
281 | (6) |
|
10.3 Defining a Method That Accepts a Simple Function Parameter |
|
|
287 | (2) |
|
10.4 Declaring More Complex Higher-Order Functions |
|
|
289 | (3) |
|
10.5 Using Partially Applied Functions |
|
|
292 | (3) |
|
10.6 Creating a Method That Returns a Function |
|
|
295 | (3) |
|
10.7 Creating Partial Functions |
|
|
298 | (5) |
|
10.8 Implementing Functional Error Handling |
|
|
303 | (2) |
|
10.9 Real-World Example: Passing Functions Around in an Algorithm |
|
|
305 | (3) |
|
10.10 Real-World Example: Functional Domain Modeling |
|
|
308 | (9) |
11 Collections: Introduction |
|
317 | (22) |
|
11.1 Choosing a Collections Class |
|
|
324 | (6) |
|
11.2 Understanding the Performance of Collections |
|
|
330 | (3) |
|
11.3 Understanding Mutable Variables with Immutable Collections |
|
|
333 | (2) |
|
11.4 Creating a Lazy View on a Collection |
|
|
335 | (4) |
12 Collections: Common Sequence Classes |
|
339 | (30) |
|
12.1 Making Vector Your Go-To Immutable Sequence |
|
|
341 | (3) |
|
12.2 Creating and Populating a List |
|
|
344 | (2) |
|
12.3 Adding Elements to a List |
|
|
346 | (3) |
|
12.4 Deleting Elements from a List (or ListBuffer) |
|
|
349 | (2) |
|
12.5 Creating a Mutable List with ListBuffer |
|
|
351 | (1) |
|
12.6 Using LazyList, a Lazy Version of a List |
|
|
352 | (3) |
|
12.7 Making ArrayBuffer Your Go-To Mutable Sequence |
|
|
355 | (2) |
|
12.8 Deleting Array and ArrayBuffer Elements |
|
|
357 | (2) |
|
12.9 Creating and Updating an Array |
|
|
359 | (3) |
|
12.10 Creating Multidimensional Arrays |
|
|
362 | (3) |
|
|
365 | (4) |
13 Collections: Common Sequence Methods |
|
369 | (50) |
|
13.1 Choosing a Collection Method to Solve a Problem |
|
|
371 | (7) |
|
13.2 Looping Over a Collection with foreach |
|
|
378 | (3) |
|
|
381 | (4) |
|
13.4 Using zipWithlndex or zip to Create Loop Counters |
|
|
385 | (2) |
|
13.5 Transforming One Collection to Another with map |
|
|
387 | (3) |
|
13.6 Flattening a List of Lists with flatten |
|
|
390 | (2) |
|
13.7 Using filter to Filter a Collection |
|
|
392 | (3) |
|
13.8 Extracting a Sequence of Elements from a Collection |
|
|
395 | (2) |
|
13.9 Splitting Sequences into Subsets |
|
|
397 | (3) |
|
13.10 Walking Through a Collection with the reduce and fold Methods |
|
|
400 | (5) |
|
13.11 Finding the Unique Elements in a Sequence |
|
|
405 | (1) |
|
13.12 Merging Sequential Collections |
|
|
406 | (3) |
|
13.13 Randomizing a Sequence |
|
|
409 | (1) |
|
13.14 Sorting a Collection |
|
|
410 | (5) |
|
13.15 Converting a Collection to a String with mkString and addString |
|
|
415 | (4) |
14 Collections: Using Maps |
|
419 | (26) |
|
14.1 Creating and Using Maps |
|
|
419 | (3) |
|
14.2 Choosing a Map Implementation |
|
|
422 | (3) |
|
14.3 Adding, Updating, and Removing Immutable Map Elements |
|
|
425 | (2) |
|
14.4 Adding, Updating, and Removing Elements in Mutable Maps |
|
|
427 | (2) |
|
14.5 Accessing Map Values (Without Exceptions) |
|
|
429 | (2) |
|
14.6 Testing for the Existence of a Key or Value in a Map |
|
|
431 | (1) |
|
14.7 Getting the Keys or Values from a Map |
|
|
432 | (1) |
|
14.8 Finding the Largest (or Smallest) Key or Value in a Map |
|
|
433 | (2) |
|
|
435 | (3) |
|
14.10 Sorting an Existing Map by Key or Value |
|
|
438 | (3) |
|
|
441 | (4) |
15 Collections: Tuple, Range, Set, Stack, and Queue |
|
445 | (18) |
|
15.1 Creating Heterogeneous Lists with Tuples |
|
|
446 | (3) |
|
|
449 | (4) |
|
15.3 Creating a Set and Adding Elements to It |
|
|
453 | (2) |
|
15.4 Deleting Elements from Sets |
|
|
455 | (2) |
|
15.5 Storing Values in a Set in Sorted Order |
|
|
457 | (1) |
|
15.6 Creating and Using a Stack |
|
|
458 | (2) |
|
15.7 Creating and Using a Queue |
|
|
460 | (3) |
16 Files and Processes |
|
463 | (24) |
|
|
464 | (4) |
|
|
468 | (2) |
|
16.3 Reading and Writing Binary Files |
|
|
470 | (2) |
|
16.4 Pretending That a String Is a File |
|
|
472 | (1) |
|
16.5 Serializing and Deserializing Objects to Files |
|
|
473 | (2) |
|
16.6 Listing Files in a Directory |
|
|
475 | (2) |
|
16.7 Executing External Commands |
|
|
477 | (3) |
|
16.8 Executing External Commands and Reading Their STDOUT |
|
|
480 | (3) |
|
16.9 Handling Both STDOUT and STDERR of Commands |
|
|
483 | (2) |
|
16.10 Building a Pipeline of External Commands |
|
|
485 | (2) |
17 Building Projects with sbt |
|
487 | (34) |
|
17.1 Creating a Project Directory Structure for sbt |
|
|
490 | (5) |
|
17.2 Building Projects with the sbt Command |
|
|
495 | (2) |
|
17.3 Understanding build.sbt Syntax Styles |
|
|
497 | (2) |
|
17.4 Compiling, Running, and Packaging a Scala Project |
|
|
499 | (2) |
|
17.5 Understanding Other sbt Commands |
|
|
501 | (3) |
|
17.6 Continuous Compiling and Testing |
|
|
504 | (1) |
|
17.7 Managing Dependencies with sbt |
|
|
505 | (5) |
|
17.8 Controlling Which Version of a Managed Dependency Is Used |
|
|
510 | (2) |
|
17.9 Generating Project API Documentation |
|
|
512 | (1) |
|
17.10 Specifying a Main Class to Run with sbt |
|
|
513 | (2) |
|
17.11 Deploying a Single Executable JAR File |
|
|
515 | (2) |
|
17.12 Publishing Your Library |
|
|
517 | (4) |
18 Concurrency with Scala Futures and Akka Actors |
|
521 | (36) |
|
|
525 | (3) |
|
18.2 Using Callback and Transformation Methods with Futures |
|
|
528 | (4) |
|
18.3 Writing Methods That Return Futures |
|
|
532 | (2) |
|
18.4 Running Multiple Futures in Parallel |
|
|
534 | (4) |
|
18.5 Creating OOP-Style Actors |
|
|
538 | (5) |
|
18.6 Creating FP-Style Actors |
|
|
543 | (3) |
|
18.7 Sending Messages to Actors |
|
|
546 | (6) |
|
18.8 Creating Actors That Have Multiple States (FSM) |
|
|
552 | (5) |
19 Play Framework and Web Services |
|
557 | (32) |
|
19.1 Creating a Play Framework Project |
|
|
558 | (6) |
|
19.2 Creating a New Play Framework Endpoint |
|
|
564 | (4) |
|
19.3 Returning JSON from a GET Request with Play |
|
|
568 | (4) |
|
19.4 Serializing a Scala Object to a JSON String |
|
|
572 | (4) |
|
19.5 Deserializing JSON into a Scala Object |
|
|
576 | (5) |
|
19.6 Using the Play JSON Library Outside of the Play Framework |
|
|
581 | (3) |
|
19.7 Using the sttp HTTP Client |
|
|
584 | (5) |
20 Apache Spark |
|
589 | (30) |
|
20.1 Getting Started with Spark |
|
|
591 | (4) |
|
20.2 Reading a File into a Spark RDD |
|
|
595 | (5) |
|
20.3 Reading a CSV File into a Spark RDD |
|
|
600 | (2) |
|
20.4 Using Spark Like a Database with DataFrames |
|
|
602 | (6) |
|
20.5 Reading Data Files into a Spark DataFrame |
|
|
608 | (4) |
|
20.6 Using Spark SQL Queries Against Multiple Files |
|
|
612 | (4) |
|
20.7 Creating a Spark Batch Application |
|
|
616 | (3) |
21 Scala.js, GraalVM, and jpackage |
|
619 | (28) |
|
21.1 Getting Started with Scala.js |
|
|
620 | (5) |
|
21.2 Responding to Events with Scala.js |
|
|
625 | (7) |
|
21.3 Building Single-Page Applications with Scala.js |
|
|
632 | (6) |
|
21.4 Building Native Executables with GraalVM |
|
|
638 | (3) |
|
21.5 Bundling Your Application with jpackage |
|
|
641 | (6) |
22 Integrating Scala with Java |
|
647 | (20) |
|
22.1 Using Java Collections in Scala |
|
|
648 | (4) |
|
22.2 Using Scala Collections in Java |
|
|
652 | (2) |
|
22.3 Using Java Optional Values in Scala |
|
|
654 | (2) |
|
22.4 Using Scala Option Values in Java |
|
|
656 | (3) |
|
22.5 Using Scala Traits in Java |
|
|
659 | (1) |
|
22.6 Using Java Interfaces in Scala |
|
|
660 | (1) |
|
22.7 Adding Exception Annotations to Scala Methods |
|
|
661 | (1) |
|
22.8 Annotating varargs Methods to Work with Java |
|
|
662 | (2) |
|
22.9 Using @SerialVersionUlD and Other Annotations |
|
|
664 | (3) |
23 Types |
|
667 | (44) |
|
23.1 Creating a Method That Takes a Simple Generic Type |
|
|
677 | (1) |
|
23.2 Creating Classes That Use Simple Generic Types |
|
|
678 | (4) |
|
23.3 Making Immutable Generic Parameters Covariant |
|
|
682 | (2) |
|
23.4 Creating a Class Whose Generic Elements Can Be Mutated |
|
|
684 | (3) |
|
23.5 Creating a Class Whose Parameters Implement a Base Type |
|
|
687 | (2) |
|
23.6 Using Duck Typing (Structural Types) |
|
|
689 | (2) |
|
23.7 Creating Meaningful Type Names with Opaque Types |
|
|
691 | (4) |
|
23.8 Using Term Inference with given and using |
|
|
695 | (6) |
|
23.9 Simulating Dynamic Typing with Union Types |
|
|
701 | (2) |
|
23.10 Declaring That a Value Is a Combination of Types |
|
|
703 | (3) |
|
23.11 Controlling How Classes Can Be Compared with Multiversal Equality |
|
|
706 | (1) |
|
23.12 Limiting Equality Comparisons with the CanEqual Typeclass |
|
|
707 | (4) |
24 Best Practices |
|
711 | (38) |
|
24.1 Writing Pure Functions |
|
|
713 | (6) |
|
24.2 Using Immutable Variables and Collections |
|
|
719 | (3) |
|
24.3 Writing Expressions (Instead of Statements) |
|
|
722 | (3) |
|
24.4 Using Match Expressions and Pattern Matching |
|
|
725 | (3) |
|
24.5 Eliminating null Values from Your Code |
|
|
728 | (5) |
|
24.6 Using Scala's Error-Handling Types (Option, Try, and Either) |
|
|
733 | (7) |
|
24.7 Building Modular Systems |
|
|
740 | (4) |
|
24.8 Handling Option Values with Higher-Order Functions |
|
|
744 | (5) |
Index |
|
749 | |