A Scala tutorial for Java developers

A Scala tutorial for Java developers

A Scala tutorial for Java developers


I was asked to prepare a 30-min presentation about the Scala programminglanguage. The target audience is a community of experienced Java developers in our organization. Taking into account the time limit and the audience type, I will go straight to the business an I will cover the core Scala features.

So, Scala was first introduced in January 2004 by Martin Odersky, it is JVM based and statically typed programming language. Scala supports both object-oriented and functional programming paradigms. The most well-known products written in Scala are Apache Spark, Apache Kafka, Apache Flink. And finally, Scala scores pretty well in programming language popularity rankings (13)

Scala pros: what makes it great

Concise syntax

Scala is designed to be concise, many of Scala’s design decisions aimed to address the verbosity of Java. For example here is the code that defines new class *UserInfo. *This class has two properties. The first one is read-write property *Name *and the second one is *BirthDate *which is read-only.

Java code:

class UserInfo {
    private String name;
    private LocalDate birthDate;

    public UserInfo(String name, LocalDate birthDate) {
        this.name = name;
        this.birthDate = birthDate;

    public String getName() {
        return name;

    public void setName(String name) {
        this.name = name;

    public LocalDate getBirthDate() {
        return birthDate;

Scala code:

class UserInfo(var name: String, val birthDate: LocalDate)

Just a bit about syntax, in Scala variable name, comes first and then comes variables type. A var is a variable. It’s a mutable reference to a value. On the other hand, val is a value, an immutable reference. In this single line, you can see the expressiveness of Scala.

Case Classes

When it comes to comparing objects in Java, it compares references. For example, the following code will return false.

LocalDate date = LocalDate.now();
UserInfo a = new UserInfo("John", date);
UserInfo b = new UserInfo("John", date);
return (a == b);

But sometimes we would like to compare objects by underlying values and not by reference. So in Java, we have to implement equals *and *hashcodemethods. In Scala, we have Case Classes. *Case Class automatically defines *equals, hashcode *methods and getters for constructor arguments. And most important it can be used in pattern matching. So by implementing UserInfo as a *Case Class, we will get the following result:

case class UserInfo(var name: String, birthDate: LocalDate)
val date = LocalDate.now()
val a = new UserInfo("John", date)
val b = new UserInfo("John", date)
a == b // returns True

Pattern matching

Pattern matching is a mechanism for checking a value against a pattern. You can think about Scala’s pattern matching as a more powerful version of switch **statement **in Java. A match expression has a value, the <strong>match</strong>keyword, and at least one <strong>case</strong>clause. Example:

def matchTest(x: Int): String = x match {
  case 1 => "one"
  case 2 => "two"
  case _ => "many"

In Scala it is possible to perform pattern matching on types:

def matchOnType(x: Any): String = x match {
  case x: Int => s"$x is integer"
  case x: String => s"$x is string"
  case _ => "unknown type"
matchOnType(1) // returns 1 is integer
matchOnType("1") // returns 1 is string

Let’s see the more powerful case. Let’s match integers sequence

def matchList(x: List[Int]): String = x match {
  case List(_) => "a single element list"
  case List(_, _) => "a two elements list"
  case List(1, _*) => "a list starting with 1"
matchList(List(3)) // returns a single elements list matchList(List(0, 1)) // returns a two elements list
matchList(List(1, 0, 0)) // returns a list starting with 1

And finally, let’s see the most powerful case: a pattern matching on case classes.

case class UserInfo(var name: String, birthDate: LocalDate)
def isUserJohn(x: Any): Boolean = x match {
  case UserInfo("John", _) => true
  case _ => false
val list = List(
  "wrong user type",
  UserInfo("Ben", LocalDate.now()),
  UserInfo("John", LocalDate.now()))
list.filter(isUserJohn) // list with one element UserInfo John

Implicit Classes

The implicit keyword makes the class’s primary constructor available for implicit conversions when the class is in scope.

Assume that you were asked to extend UserInfo class with a getAge method. So there are two options. Create a separate library of UserInfo utility methods, like an *UserInfoUtil *class or to create a subclass which inherits all attributes and methods of UserInfo and extends it with *getAge. *In Scala, you can add your own behavior(s) by using implicit class.

object Extensions {
  implicit class UserInfoExt(user: UserInfo) {
    def getAge(): Int = {
      Years.yearsBetween(LocalDate.now(), user.birthDate,).getYears

This will let you write the code like this

import Extensions._
val user = new UserInfo("John", LocalDate.now())

Higher-order functions

Scala allows the definition of higher-order functions. These are functions that take other functions as parameters, or whose result is a function. The classic examples of higher-order functions are map and **filter.

*Map *applies a function on all elements of a collection. For example, let’s multiply by 2 each element of a given list

def multiply(x: Int): Int = x * 2

List(1, 2, 3).map(multiply) // returns 2 4 6 

*Filter *creates a list of elements for which a function returns true. Here is a short and concise example:

def isEven(x: Int): Boolean = x % 2 == 0
List(1, 2, 3).filter(isEven) // returns 2

Let’s define our own higher-order function:

def apply(f: Int => String, x: Int): String = f(x)
def printInt(x: Int): String = s"Printing integer $x"
apply(printInt, 3)

Option Monad

Monad is a design pattern that allows structuring programs generically while automating away boilerplate code needed by the program logic and provides an easy way for composing and sequencing operations on some contained value(s).

I would like to mention that I am not going to go deep to Monad’s theory. My only point is to show how Scala Option Monad can help to deal with ‘coping with errors’ problem that is very common in many languages. Consider the following code:

class Document {
  def getActivePage: Page = ???
class Page {
  def getSelectedText: String = ???

The goal is to implement getSelectedTextLength method which returns the length of selected text on the active page, otherwise, it returns 0. The simple approach is to implement it as follows:

def getSelectedTextLength(doc: Document): Int = {
  if(doc != null) {
    val page = doc.getActivePage
    if(page != null){
      val text = page.getSelectedText
      if(text != null){
      else 0
    else 0
  else 0

Such implementation is OK, but it has nested indentation, aka pyramid of doom. There is another way to implement it:

def getSelectedTextLength(doc: Document): Int = {
  if(doc == null)
    return 0

  val page = doc.getActivePage
  if(page == null)
    return 0

  val text = page.getSelectedText
  if(text == null)
    return 0


It looks flat and clean but has if (x == null) return 0 a pattern which appears many times. We can simplify it by using exceptions:

def getSelectedTextLength(doc: Document): Int = {
  try {
  catch {
    case _: NullPointerException => 0
    case e: Exception => throw e

This version looks good but has some problem though. If NullPointerExceptionis thrown from getActivePage or getSelectedText it will be unintentionally handled by our code and by doing so, our code will hide the potential bug.

In Scala it can be solved by using Option Monad. Option monad wrappes value of any given type and have two specific implementations: None when a value does not exist (null) or Some for the existing value, plus it defines flatMap operation which allows composing operations sequence together.

trait Option[A] {
  def flatMap[B](f: A => Option[B]): Option[B]

case class None[A]() extends Option[A] {
  def flatMap[B](f: A => Option[B]): Option[B] = new None

case class Some[A](a: A) extends Option[A] {
  def flatMap[B](f: A => Option[B]): Option[B] = {

So by using Option monad, we can reimplement the code as follows

class Document {
  def getActivePage: Option[Page] = ???
class Page {
  def getSelectedText: Option[String] = ???

def getSelectedTextLength(doc: Option[Document]): Int = {


Scala isn’t perfect, it comes with its own limitation and drawbacks. It has a steep learning curve because its principles are based on mathematical type theory which is hard to master. When not maintained carefully, the Scala source code is hard to read and understand. Some big tech companies like LinkedIn, Twitter, Yammer reported that they are abandoning or decreasing their dependency on Scala.

On the other hand, Scala is flexible, productive and comes with a pretty rich toolbox. Compatibility with Java allows Scala developers to enjoy of rich Java ecosystem of libraries, frameworks, and tools. All these facts make Scala my language of choice when it comes to developing Big Data pipelines or high load server backends.

scala java

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

How to Install OpenJDK 11 on CentOS 8

What is OpenJDK? OpenJDk or Open Java Development Kit is a free, open-source framework of the Java Platform, Standard Edition (or Java SE).

Java and Scala: Why Should You Learn Scala?

Java is a general purpose object oriented language. Scala is less readable due to nested code. The process of compiling source code into byte code is slow. ... Scala treated everything as an instance of the class and it is more object oriented language as compare to Java.

Java Core (2020) | Java for beginners | Brush up your Java Skills | Get Hired

In this video we will learn about all the major concepts that come under Java Core . The course is very carefully designed and is made with keeping simplicit...

Exception handling in Scala

Scala is functional programming language. Except for the side effects that have a return type of Unit or (), everything else returns a value in scala. Scala treats everything as an expression and that is what makes scala such a powerful language.

Java Multithreading Example | Multithreading in Java

Java Multithreading Tutorial With Example | Multithreading in Java. Multithreading is a process of executing multiple threads simultaneously.