Scala for Java Developers

Scala type hierarchy

Scala class hierarchy image

Basic Types and Operations

127 – The convention is to include empty parentheses when invoking a method only if that method has side effects

  • Pure methods are methods that don’t have any side effects and don’t depend on mutable state (226)
  • if the function you’re calling performs an operation, use the parentheses, but if it merely provides access to a property, leave out the parentheses

127 – Postfix operator: A method that takes no arguments can be called like this: "some String" toLowerCase
127 – Integral types: Int, Long, Byte, Short, Char

135 – Operator precedence:

(all other special characters)
* / %
+ -
= !
< >
ˆ – binary xor
(all letters)
(all assignment operators)

Operator precedence is based on the first character of the method used in operator notation, with one exception: If an operator ends with a =, and the operator is not one of the comparison operators <=, >=, ==, or !=, then the precedence of the operator is the same as that of simple assignment =, which is last in the list. E.g. +=

136 – Associativity

  • any method that ends in a : character is invoked on its right operand, passing in the left operand. Methods that end in any other character are invoked on their left operand, passing in the right operand. So a * b yields a.*(b), but a ::: b yields b.:::(a)

137 – a ::: b ::: c is treated as a ::: (b ::: c) (list concatenation)

Functional Objects

141 – Class parameters: Any code placed in the class body (outside methods) will be placed in the primary constructor. When declaring a class you can drop empty {}
143 – Precondition is a constraint on values passed into a method or constructor (E.g. require(d != 0) in the class body will throw IllegalArgumentException: requirement failed when 0 is passed as d)
144 – If Class parameters are only used inside constructors, the Scala compiler will not create corresponding fields for them
146 – Auxiliary constructors – constructors other than the primary constructor

  • every auxiliary constructor must invoke another constructor of the same class (like Java, only Java can also call superclass’s constructor instead) as its first action. That other constructor must textually come before the calling constructor

152 – The convention is to use camel case for constants, such as XOffset
153 – The Scala compiler will internally “mangle” operator identifiers to turn them into legal Java identifiers with embedded $ characters. For instance, the identifier :-> would be represented internally as $colon$minus$greater. If you ever wanted to access this identifier from Java code, you’d need to use this internal representation
153 – Mixed identifier consists of an alphanumeric identifier, which is followed by an underscore and an operator identifier, e.g. unary_+ (used to support properties)
153 – Literal identifier is an arbitrary string enclosed in back ticks. Used to tell Scala to treat a keyword as an ordinary identifier, e.g., writing Thread.'yield'() treats yield as an identifier rather than a keyword
156 – Implicit conversion definition:

  • for an implicit conversion to work, it needs to be in scope. If you place the implicit method definition inside the class Rational, it won’t be in scope

Built-in Control Structures

163 – Assignment always results with the unit value, ()
164 – In for (file <- files) the <- is called a generator. In each iteration, a new val named file is initialized with an element value
164 – The Range type: 4 to 8. If you don’t want upper bound: 4 until 8
166 – Filter: for (file <- files if file.getName.endsWith(".scala"))

// multiple filters example:for(file<-files// files is a previously defined method that returns array of filesiffile.isFileiffile.getName.endsWith(“.scala”))println(file)

167 – Nested loops and mid-stream variable binding example with generators and filters

deffileLines( curly braces may be used instead of parentheses// the compiler does not infer semicolons inside regular parenthesesdefgrep(pattern:String)=for{file<-filesiffile.getName.endsWith(“.scala”)// semicolons inferredline<-fileLines(file)trimmed=line.trim// mid-stream variableiftrimmed.matches(pattern)}println(file+“: “+trimmed)

168 – yield keyword makes for clauses produce a value (of the same type as the expression iterated over). Syntax: for clauses yield body
174 – match case

  • unlike Java’s select case, there is no fall through, break is implicit and case expression can contain any type of value
  • _ is a placeholder for completely unknown value
valtarget=firstArgmatch{// firstArg is a previously initialized valcase“salt”=>println(“pepper”)case“chips”=>println(“salsa”)case“eggs”=>println(“bacon”)case_=>println(“waat?”)}

175 – Scala doesn’t have break, nor does it have continue statement
180 – Unlike Java, Scala supports inner scope variable shadowing