Scala for Java developers

Lesson 4: FP & OOP

Function

1. map

 

2. filter

 

3. fold

 

4. foldLeft

Definition

def doSomething(f: (A) ⇒ B): List[B]
def doSomething(p: (A) ⇒ Boolean): List[A]
def doSomething[A1 >: A](z: A1)(op: (A1, A1) ⇒ A1): A1
def doSomething[B](z: B)(op: (B, A) ⇒ B): B

Quiz recap

Function

1. map

 

2. filter

 

3. fold

 

4. foldLeft

Definition

def doSomething(f: (A) ⇒ B): List[B]
def doSomething(p: (A) ⇒ Boolean): List[A]
def doSomething[A1 >: A](z: A1)(op: (A1, A1) ⇒ A1): A1
def doSomething[B](z: B)(op: (B, A) ⇒ B): B

Quiz recap

More higher order functions

find, reduceLeft, reduceRight

find

  • find: find the first element that satisfying a predicate p.

 

 

 

Example

def find(p: A => Boolean): Option[A]
val numbers = List(1,2,3,4,5)

numbers.find(number => number % 3 == 0)
// res0: Option[Int] = Some(3)

numbers.find(number => number % 6 == 0)
// res1: Option[Int] = None

reduceLeft & reduceRight

  • reduceLeft/ reduceRight: iterates over a data structure of type A and aggregates all elements while applying given function with end result of type B >: A

 

 

 

  • similar to foldLeft and foldRight but without initial/default value 

 

 

* B >: A means that the type parameter B or the abstract type B refer to a supertype of type A

 def reduceLeft[B >: A](op: (B, A) => B): B
 def reduceRight[B >: A](op: (A, B) => B): B
def foldLeft[B](z: B)(op: (B, A) => B): B
def foldRight[B](z: B)(op: (A, B) => B): B

Example reduceLeft & reduceRight

  
val numbers = List(1,2,3,4,5) 

findMin(numbers)
// res1: Int = 1

findMin2(numbers)
// res2: Int = 1
  def findMin(list: List[Int]): Int = {
    list.reduceLeft { (a, b) => if (a <= b) a else b }
  }
  def findMin2(list: List[Int]): Int = {
    list.reduceRight { (a, b) => if (a <= b) a else b }
  }
findMin(List.empty[Int])
java.lang.UnsupportedOperationException: empty.reduceLeft
  at scala.collection.LinearSeqOptimized.reduceLeft(LinearSeqOptimized.scala:135)
  at scala.collection.LinearSeqOptimized.reduceLeft$(LinearSeqOptimized.scala:134)
  at scala.collection.immutable.List.reduceLeft(List.scala:86)
  at .findMin(<console>:12)
  ... 38 elided

OOP

traits, case classes

traits

trait <identifier> [extends <identifier>] [{ fields, methods, and classes }]

trait

  • A trait is an abstract interface
  • Similar to Java 8 interface, it may contain implementation of some methods

 

Example

trait HotelService {
  def getHotelNames(hotels: List[Hotel]): List[String]

  def findHotelById(hotels: List[Hotel], id: Int): Option[Hotel]

  def findHotelsByCity(hotels: List[Hotel], city: String): List[Hotel]

  def findCheapestHotel(hotels: List[Hotel]): Hotel
}
trait <identifier> [extends <identifier>] [{ fields, methods, and classes }]

trait

class HotelServiceImpl extends HotelService {
  
  override def getHotelNames(hotels: List[Hotel]): List[String] = ???

  override def findHotelById(hotels: List[Hotel], id: Int): Option[Hotel] = ???

  override def findHotelsByCity(hotels: List[Hotel], city: String): List[Hotel] = ???

  override def findCheapestHotel(hotels: List[Hotel]): Hotel = ???

}

Using a trait

trait

trait PricingService {
  def convertToExchangeRate(prices: List[Integer], rate: Float): List[Integer]

  def findPricesBelowThreshold(prices: List[Integer], threshold: Integer): List[Integer]

  def findMaxPrice(prices: List[Integer]): Option[Integer] = {
    if (prices.isEmpty)
      None
    else
      Some(prices.max)
  }
}

Example with a implemented method

case classes

case class <identifier> ([var] <identifier>: <type>[, ... ])
                        [extends <identifier>(<input parameters>)]
                        [{ fields and methods }]

case class

  • Kind of POJO object but simpler
  • Good for modelling immutable data or DTO
class Hotel {
    private String name;
    private String city;
    private Integer price;

    Hotel(String name, String city, Integer price) {
        this.name = name;
        this.city = city;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public String getCity() {
        return city;
    }

    public Integer getPrice() {
        return price;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Hotel hotel = (Hotel) o;

        if (name != null ? !name.equals(hotel.name) : hotel.name != null) return false;
        if (city != null ? !city.equals(hotel.city) : hotel.city != null) return false;
        return price != null ? price.equals(hotel.price) : hotel.price == null;

    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (city != null ? city.hashCode() : 0);
        result = 31 * result + (price != null ? price.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "Hotel(" + name + ", " + city + ", " + price + ')';
    }
}
case class Hotel(name: String, city: String, price: Int)

case class

  • A case class is similar to a regular class but with some differences:
    • No need of new keyword to create an instance
    • By default parameters of a case class are public value fields, i.e. val
    • Implements equals, hashCode and a nice toString
    • Has a copy method
case class Hotel(name: String, city: String, price: Int)
case class <identifier> ([var] <identifier>: <type>[, ... ])
                        [extends <identifier>(<input parameters>)]
                        [{ fields and methods }]

case class

case class Hotel(name: String, city: String, price: Int)

// new case class instance

val hiltonHotel = Hotel("Hilton London Canary Wharf", "London", 111)
// Using the copy method

val hiltonHotel2 = hiltonHotel.copy(name = "DoubleTree by Hilton - Chelsea")
// hiltonHotel2: Hotel = Hotel(DoubleTree by Hilton - Chelsea,London,111)
// Accessing parameters

val hilton2Nigths = hiltonHotel.price * 2
// hilton2Nigths: Int = 222
// using default toString

println(hiltonHotel)
// Hotel(Hilton London Canary Wharf,London,111)

Time for exercises!

Give us your feedback :)

https://goo.gl/forms/hXIvwwhslM0yXEC83

Made with Slides.com