Sonia Fernández Rodríguez
Software Engineer
1. map
2. filter
3. fold
4. foldLeft
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
1. map
2. filter
3. fold
4. foldLeft
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
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
* 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
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
trait <identifier> [extends <identifier>] [{ fields, methods, and classes }]
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 }]
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 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 class <identifier> ([var] <identifier>: <type>[, ... ])
[extends <identifier>(<input parameters>)]
[{ fields and methods }]
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 Hotel(name: String, city: String, price: Int)
case class <identifier> ([var] <identifier>: <type>[, ... ])
[extends <identifier>(<input parameters>)]
[{ fields and methods }]
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)
Give us your feedback :)
By Sonia Fernández Rodríguez
Scala for Java developers. Lesson 4. Higher order functions (find and reduce). Case classes and traits