SlideShare uma empresa Scribd logo
1 de 9
Baixar para ler offline
Scala Collections API
Expressivity and Brevity upgrade from Java
Dhananjay Nene
IndicThreads Conference On Java
December 2, 2011


Scala Collections
Some of the basic scala collection types are :

   • HashSet
   • Sequence
   • Vector
   • List
   • Stream
   • Queue
   • Stack

Largely focus on Lists
We shall predominantly focus on lists with a slightly lesser focus on other types. Most of the frequently
used operations are available on lists, so these are a good starting point.


Simple List Construction
 val cities = List("Pune", "Mumbai", "Bangalore", "Kolkata", "New Delhi")
 val primes = List(2,3,5,7,11,13)

Note :

   • No "new" .. but thats syntax sugar
   • No type declaration. The types are inferred to be List[String] & List[Int]
   • No semi colons at the end

A simple list iteration
Code closest to java

 val numbers = List(1,3,5,9)
 for(n <- numbers) {
   println(n)
 }

But thats not the only way
A simple recursion traversal
def recursionTraversal(numbers: List[Int]): Unit = {
  if ((numbers length) > 0) {
    println(numbers head); recursionTraversal(numbers tail)
  }
}

recursionTraversal(List(1,3,5,9))


  • Did you notice the function arguments ?
  • And what is "numbers length"? Ans: It is the same as numbers.length().
  • Can you figure out what "numbers head" and "numbers tail" do?

A different recursion traversal
patternMatchingTraversal(1 :: (3 :: (5 :: (9 :: Nil))))
def patternMatchingTraversal(numbers: List[Int]): Unit = {
  numbers match {
    case h :: t =>
      println(h)
      patternMatchingTraversal(t)
    case _ => ; // DO Nothing
  }
}


  • Note how the list is created. And the pattern matching too

Other List Methods
  • length : Length of list
  • reverse : Reverse a list
  • toArray : Convert to array
  • iterator & next : Iterator protocol
  • mkString : Concatenate elements into a string
  • apply : Random element access
  • init : All but last element in a list
  • last : Last element in a list

Patterns of collection computations
  • There are some frequently occurring general purpose patterns used over collections.
  • These are all a part of the scala collections API.
  • This is one area where you will find a significant expressivity and brevity upgrade over java.
map : Applying to each element
def double(x: Int) = x * 2

List(1,3,5) map double
// OR
List(1,3,5) map {n => n * 2}
// OR
List(1,3,5) map {_ * 2}
// All result into List(2, 6, 10)


 • Note the inline and anonymous function declarations the the parameter "_"

Equivalent Java Code
public static List<Integer>
    doubleAll(List<Integer> numbers) {
    List<Integer> doubled = new LinkedList<Integer>();
    for(Integer n : numbers) {
      doubled.add(n * 2);
    }
    return doubled;
}
public static void main(String[] args) {
    System.out.println(doubleAll(Arrays.asList(1,3,5)));
}


Regarding map
 • In the earlier example, how would you write tripleAll instead of doubleAll? Ans: Copy the entire
   function and modify slightly.
 • Map is a very frequently occurring operation on collections
 • The process of mapping is abstracted away orthogonally from the operation performed on each
   element
 • This results in a substantial reduction in size
 • This also removes a lot of ceremony and boilerplate.

Regarding map .. 2
 • You focus on the very essence of what is being done eg. myList map double
 • Stripping away of ceremony & boiler plate, and ability to focus on the essence, is a consistent
   characteristic of many methods on List & other collections
 • If you think about it, you will find lots and lots of uses of map in your regular tasks eg. computation of
   tax on each item in a list
 • When we pass a function as an argument to a function (or expect a function as a return type), thats
   termed Higher Order Functions (HOFs). eg. double
filter : Selecting elements
 // select only odd numbers from a list
 List(1,2,3,4,5) filter { _%2 != 0}
 // results into List(1, 3, 5)


   • Again this is a frequently used pattern. Again scala strips away the ceremony and allows you to
     focus on the essence. (I'll stop repeating this)
   • Also notice the predicate selecting odd numbers being used as a HOF (I'll stop repeating this too).

fold : Summarising / Aggregation
 (0 /: List(1,2,3,4)) {(sum,num) => sum + num}
 List(1,2,3,4).foldLeft(0){(sum,num) => sum + num}
 List(1,2,3,4).foldLeft(0){_ + _}
 // All result in the value 10


   • Yet again, a frequently found pattern. eg. creating total for an invoice

Other Patterns
   • take and takeWhile : Select first few elements of a list
   • drop and dropWhile : Select last few elements of a list
   • zip and unzip : Combine two lists into list of pairs (& vice-versa)
   • partition : Split a list into two based on a predicate
   • forall and exists : Test all or any one element of a list for a predicate
   • sortWith : Sort given a comparation predicate
   • flatten : Flatten a List of List of X into a List of X
   • flatMap : Flatten a List of List obtained by mapping a function that returns a list

Back to iteration over a list
Earlier we saw a for loop and a recursive method of traversing a list. One might be tempted to use map to
print all elements of a list

 // Whats the return value ?
 List(1,2,3,4) map { println _ }

 // When you are not interested in the return value
 // interested only in the side effects of the function
 List(1,2,3,4) foreach { println _ }


For Comprehensions
Combines for loops, filters, and assignments
case class Cell(val row: Int, val col: Int)
def isOccupied(c: (Int, Int)) = (c._1 + c._2) % 2 == 0

def findFreeCells(): List[String] = {
  val p = for(i <- 1 to 3;
              j <- 1 to 3;
              cell = (i,j);
              if (!isOccupied(cell))
              ) yield (List(i,j).mkString("C","",""))
  p toList
}


Equivalent Java Code
class Cell {
    private Integer row;
    private Integer col;

    public Cell(Integer row, Integer col) {
        this.row = row;
        this.col = col;
    }

    public Integer getRow() {
        return this.row;
    }


Java code continued...
    public Integer getCol() {
        return this.col;
    }
}

public static boolean isOccupied(Cell cell) {
    return ((cell.getRow() + cell.getCol()) % 2) == 0;
}
Java code continued...
public static List<String> findFreeCells() {
    List<String> retList = new LinkedList<String>();
    for(int i = 1 ; i <= 3 ; i++) {
        for(int j = 1 ; j <= 3 ; j++) {
            Cell c = new Cell(i,j);
            if (isOccupied(c) == false) {
                retList.add("C" + c.getRow() + c.getCol());
            }
        }
    }
    return retList;
}


Aside: Case classes
 • Case classes are simple java beans like classes.
 • scala throws in getters / setters / hashCode / toString / equals etc. automatically.
 • Also quite useful when pattern matching (beyond scope of this talk)
 • Can also add additional methods

case class Cell(val row: Int, val col: Int) {
  def isOccupied = (row + col) % 2 == 0
}


Maps
val states = Map("GJ" -> "Gujarat", "MH" -> "Maharashtra", "KL" -> "Kerala")
states get "GJ"
states("GJ")
states("ZZ") // will raise an exception
states.getOrElse("ZZ","Unknown")
states + ("SK" -> "Sikkim")
states - "KL"
states filterKeys {_(0) == 'G'}
states filter {_._2.length() <= 7}
states transform {(key,value) => value.toLowerCase }


Other collections
 • Set (HashSet / TreeSet) : Fairly similar semantics. Few extra eg. intersect, union, diff
 • Vector : Indexed access, Constant time non head access
 • Queue
 • Stack
Streams
Lazily evaluated.

 def fibonacci(first: Int, second: Int): Stream[Int] =
   first #:: fibonacci(second, first + second)
 val f = fibonacci(1,1)
 // result = List(1, 1, 2, 3, 5, 8, 13)
 f.takeWhile {_ < 20} toList


Mutable or Immutable
   • Most collections come in both mutable and immutable variants
   • (Surprisingly?) the preferred usage is immutable
   • A detailed discussion on the matter is beyond the scope of the talk
   • A good java equivalent to immutable classes is String. Think the same design principles applied
     across the collections.
   • Just like string, there exist mutable Buffer/Builder classes to slowly collect elements of a collection
     and finally convert them into an immutable collection.

Parallel Collections
 (1 to 10) foreach {println}
 (1 to 10).par foreach {println}


Sample Code
(To be shown separately)

 package ordersystem
 import scala.collection.mutable

 case class CustomerOrder(                val   orderId: String,
                                          val   customerCode: String,
                                          val   productCode: String,
                                          val   quantity: Int)

 case class ProductMaster(                val productCode: String,
                                          val manufacturingTime: Int,
                                          val components: List[(String,Int)])

 case class ShippingNote(                 val customerCode: String,
                                          val items: List[ShipItem])

 case class ShipItem(                     val   customerCode: String,
                                          val   orderId: String,
                                          val   productCode: String,
                                          val   quantity: Int)

 case class MakeProduct(                  val customerCode: String,
                                          val orderId: String,
val productCode: String,
                                val quantity: Int)

object OrderSystem {
  var inventory = mutable.Map("foo" -> 14,
                      "bar" -> 14,
                      "baz" -> 14)

  val productMaster =    List( ProductMaster("foo",5,List(("zoo", 7),("zar",9))),
                               ProductMaster("bar",7,List(("boo", 9),("moo",6))),
                               ProductMaster ("baz",6,List(("zar",4),("moo",5)))) map {p => p.productCode -> p} toMap

  val itemInventory = mutable.Map("zoo" -> 80, "zar" -> 100, "boo" -> 25, "moo" -> 30)

  def shipOrMake(order: CustomerOrder) = {
    // find existing available products in stock
    val available = inventory.getOrElse(order.productCode,0)

      // compute products that can be shipped, updated stocks and those that need to be made
      val (ship, stock, make) =
        if (order.quantity < available) (order.quantity, available - order.quantity, 0)
        else (available, 0, order.quantity - available)
      inventory.put(order.productCode,stock)

      // create shipment instruction
      val shipItem = if (ship > 0) Some(ShipItem(order.customerCode, order.orderId, order.productCode, ship)) else None
      println("Ship:" + shipItem)

      // and/or make product instruction
      val makeProduct = if (make > 0) Some(MakeProduct(order.customerCode, order.orderId, order.productCode, make)) else None
      (shipItem, makeProduct)
  }

  def main(args: Array[String])   = {
    val orders = List(
      CustomerOrder("c11","c1",   "foo",   10),
      CustomerOrder("c12","c1",   "bar",   12),
      CustomerOrder("c12","c1",   "baz",   14),
      CustomerOrder("c21","c2",   "foo",   12),
      CustomerOrder("c22","c2",   "bar",   10),
      CustomerOrder("c22","c2",   "baz",   12))

      // find which products to ship directly and which to make
      val shipMakeProducts = orders map shipOrMake // will give shipitem and makeitem

      // create ship item notices
      val shipItems = (shipMakeProducts map {_._1} flatten) groupBy {_.customerCode} map { x => ShippingNote(x._1,x._2) };
      println(shipItems)

      // create make product notices
      val makeProducts = shipMakeProducts map {_._2} flatten   ;
      println(makeProducts)

      val todo = makeProducts map { order =>
        // for each product that has to be made
        // get the corresponding product master




            println("Processing Make Product Order:" + order)
            productMaster.get(order.productCode) match {
              case Some(master) =>
                // for each of the components required
                master.components map {
                    // compute the quantities of items required
                    pmc => (pmc._1, pmc._2 * order.quantity)
                  } map { requiredPair =>

                         val item = requiredPair._1
                         val itemQuantity = requiredPair._2

                         // compare with available quantities
                         val available = itemInventory.getOrElse(item,0)
                         // requisition if not available
                         val (used, requisitioned) = if (available >= itemQuantity) {
                           (itemQuantity,0)
                         } else {
                           (available, itemQuantity - available)
}
                   itemInventory.put(item,available - used)
                   println("Using " + used + " units of " + item + " and requisitioning " + requisitioned)
                   (item,used,requisitioned)
                }
            case None =>
              throw new Exception("product not in product master")
           }
         }
         // flatten the resultant list and group by item code
         val itemMap = (todo flatten) groupBy {_._1}
         println(itemMap)
         // for each item, fold the corresponding list to arrive at cumulative totals
         val itemMap2 = itemMap map {keyVal =>
           (keyVal._1,((0,0) /: keyVal._2){(total,each) => (total._1 + each._2, total._2 + each._3)})
         }
         println(itemMap2)
     }
 }



Thank You
Contact Information:
Dhananjay Nene
Vayana Services
http://blog.dhananjaynene.com
http://twitter.com/dnene
firstname dot lastname at gmail dot com

Mais conteúdo relacionado

Mais procurados

High Wizardry in the Land of Scala
High Wizardry in the Land of ScalaHigh Wizardry in the Land of Scala
High Wizardry in the Land of Scala
djspiewak
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
Hiroshi Ono
 

Mais procurados (18)

Scala Bootcamp 1
Scala Bootcamp 1Scala Bootcamp 1
Scala Bootcamp 1
 
Intro to Functional Programming in Scala
Intro to Functional Programming in ScalaIntro to Functional Programming in Scala
Intro to Functional Programming in Scala
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: Notes
 
Scala Paradigms
Scala ParadigmsScala Paradigms
Scala Paradigms
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Scala jargon cheatsheet
Scala jargon cheatsheetScala jargon cheatsheet
Scala jargon cheatsheet
 
An introduction to scala
An introduction to scalaAn introduction to scala
An introduction to scala
 
Practical cats
Practical catsPractical cats
Practical cats
 
High Wizardry in the Land of Scala
High Wizardry in the Land of ScalaHigh Wizardry in the Land of Scala
High Wizardry in the Land of Scala
 
Type Parameterization
Type ParameterizationType Parameterization
Type Parameterization
 
Effective way to code in Scala
Effective way to code in ScalaEffective way to code in Scala
Effective way to code in Scala
 
Real generics
Real genericsReal generics
Real generics
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
An Introduction to Part of C++ STL
An Introduction to Part of C++ STLAn Introduction to Part of C++ STL
An Introduction to Part of C++ STL
 
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
 

Semelhante a Scala collections api expressivity and brevity upgrade from java

(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
Tomasz Wrobel
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
shinolajla
 
Stl (standard template library)
Stl (standard template library)Stl (standard template library)
Stl (standard template library)
Hemant Jain
 
Underscore.js
Underscore.jsUnderscore.js
Underscore.js
timourian
 

Semelhante a Scala collections api expressivity and brevity upgrade from java (20)

(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009
 
16. Arrays Lists Stacks Queues
16. Arrays Lists Stacks Queues16. Arrays Lists Stacks Queues
16. Arrays Lists Stacks Queues
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
 
Meet scala
Meet scalaMeet scala
Meet scala
 
standard template library(STL) in C++
standard template library(STL) in C++standard template library(STL) in C++
standard template library(STL) in C++
 
A Brief Intro to Scala
A Brief Intro to ScalaA Brief Intro to Scala
A Brief Intro to Scala
 
Scala or functional programming from a python developer's perspective
Scala or functional programming from a python developer's perspectiveScala or functional programming from a python developer's perspective
Scala or functional programming from a python developer's perspective
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Stl (standard template library)
Stl (standard template library)Stl (standard template library)
Stl (standard template library)
 
Introduction to parallel and distributed computation with spark
Introduction to parallel and distributed computation with sparkIntroduction to parallel and distributed computation with spark
Introduction to parallel and distributed computation with spark
 
An introduction to functional programming with Swift
An introduction to functional programming with SwiftAn introduction to functional programming with Swift
An introduction to functional programming with Swift
 
Collections In Scala
Collections In ScalaCollections In Scala
Collections In Scala
 
Scala
ScalaScala
Scala
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
Collections
CollectionsCollections
Collections
 
Underscore.js
Underscore.jsUnderscore.js
Underscore.js
 
Java10 Collections and Information
Java10 Collections and InformationJava10 Collections and Information
Java10 Collections and Information
 
Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)
 

Mais de IndicThreads

Scrap Your MapReduce - Apache Spark
 Scrap Your MapReduce - Apache Spark Scrap Your MapReduce - Apache Spark
Scrap Your MapReduce - Apache Spark
IndicThreads
 
Continuous Integration (CI) and Continuous Delivery (CD) using Jenkins & Docker
 Continuous Integration (CI) and Continuous Delivery (CD) using Jenkins & Docker Continuous Integration (CI) and Continuous Delivery (CD) using Jenkins & Docker
Continuous Integration (CI) and Continuous Delivery (CD) using Jenkins & Docker
IndicThreads
 
Unraveling OpenStack Clouds
 Unraveling OpenStack Clouds Unraveling OpenStack Clouds
Unraveling OpenStack Clouds
IndicThreads
 

Mais de IndicThreads (20)

Http2 is here! And why the web needs it
Http2 is here! And why the web needs itHttp2 is here! And why the web needs it
Http2 is here! And why the web needs it
 
Understanding Bitcoin (Blockchain) and its Potential for Disruptive Applications
Understanding Bitcoin (Blockchain) and its Potential for Disruptive ApplicationsUnderstanding Bitcoin (Blockchain) and its Potential for Disruptive Applications
Understanding Bitcoin (Blockchain) and its Potential for Disruptive Applications
 
Go Programming Language - Learning The Go Lang way
Go Programming Language - Learning The Go Lang wayGo Programming Language - Learning The Go Lang way
Go Programming Language - Learning The Go Lang way
 
Building Resilient Microservices
Building Resilient Microservices Building Resilient Microservices
Building Resilient Microservices
 
App using golang indicthreads
App using golang  indicthreadsApp using golang  indicthreads
App using golang indicthreads
 
Building on quicksand microservices indicthreads
Building on quicksand microservices  indicthreadsBuilding on quicksand microservices  indicthreads
Building on quicksand microservices indicthreads
 
How to Think in RxJava Before Reacting
How to Think in RxJava Before ReactingHow to Think in RxJava Before Reacting
How to Think in RxJava Before Reacting
 
Iot secure connected devices indicthreads
Iot secure connected devices indicthreadsIot secure connected devices indicthreads
Iot secure connected devices indicthreads
 
Real world IoT for enterprises
Real world IoT for enterprisesReal world IoT for enterprises
Real world IoT for enterprises
 
IoT testing and quality assurance indicthreads
IoT testing and quality assurance indicthreadsIoT testing and quality assurance indicthreads
IoT testing and quality assurance indicthreads
 
Functional Programming Past Present Future
Functional Programming Past Present FutureFunctional Programming Past Present Future
Functional Programming Past Present Future
 
Harnessing the Power of Java 8 Streams
Harnessing the Power of Java 8 Streams Harnessing the Power of Java 8 Streams
Harnessing the Power of Java 8 Streams
 
Building & scaling a live streaming mobile platform - Gr8 road to fame
Building & scaling a live streaming mobile platform - Gr8 road to fameBuilding & scaling a live streaming mobile platform - Gr8 road to fame
Building & scaling a live streaming mobile platform - Gr8 road to fame
 
Internet of things architecture perspective - IndicThreads Conference
Internet of things architecture perspective - IndicThreads ConferenceInternet of things architecture perspective - IndicThreads Conference
Internet of things architecture perspective - IndicThreads Conference
 
Cars and Computers: Building a Java Carputer
 Cars and Computers: Building a Java Carputer Cars and Computers: Building a Java Carputer
Cars and Computers: Building a Java Carputer
 
Scrap Your MapReduce - Apache Spark
 Scrap Your MapReduce - Apache Spark Scrap Your MapReduce - Apache Spark
Scrap Your MapReduce - Apache Spark
 
Continuous Integration (CI) and Continuous Delivery (CD) using Jenkins & Docker
 Continuous Integration (CI) and Continuous Delivery (CD) using Jenkins & Docker Continuous Integration (CI) and Continuous Delivery (CD) using Jenkins & Docker
Continuous Integration (CI) and Continuous Delivery (CD) using Jenkins & Docker
 
Speed up your build pipeline for faster feedback
Speed up your build pipeline for faster feedbackSpeed up your build pipeline for faster feedback
Speed up your build pipeline for faster feedback
 
Unraveling OpenStack Clouds
 Unraveling OpenStack Clouds Unraveling OpenStack Clouds
Unraveling OpenStack Clouds
 
Digital Transformation of the Enterprise. What IT leaders need to know!
Digital Transformation of the Enterprise. What IT  leaders need to know!Digital Transformation of the Enterprise. What IT  leaders need to know!
Digital Transformation of the Enterprise. What IT leaders need to know!
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Último (20)

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 

Scala collections api expressivity and brevity upgrade from java

  • 1. Scala Collections API Expressivity and Brevity upgrade from Java Dhananjay Nene IndicThreads Conference On Java December 2, 2011 Scala Collections Some of the basic scala collection types are : • HashSet • Sequence • Vector • List • Stream • Queue • Stack Largely focus on Lists We shall predominantly focus on lists with a slightly lesser focus on other types. Most of the frequently used operations are available on lists, so these are a good starting point. Simple List Construction val cities = List("Pune", "Mumbai", "Bangalore", "Kolkata", "New Delhi") val primes = List(2,3,5,7,11,13) Note : • No "new" .. but thats syntax sugar • No type declaration. The types are inferred to be List[String] & List[Int] • No semi colons at the end A simple list iteration Code closest to java val numbers = List(1,3,5,9) for(n <- numbers) { println(n) } But thats not the only way
  • 2. A simple recursion traversal def recursionTraversal(numbers: List[Int]): Unit = { if ((numbers length) > 0) { println(numbers head); recursionTraversal(numbers tail) } } recursionTraversal(List(1,3,5,9)) • Did you notice the function arguments ? • And what is "numbers length"? Ans: It is the same as numbers.length(). • Can you figure out what "numbers head" and "numbers tail" do? A different recursion traversal patternMatchingTraversal(1 :: (3 :: (5 :: (9 :: Nil)))) def patternMatchingTraversal(numbers: List[Int]): Unit = { numbers match { case h :: t => println(h) patternMatchingTraversal(t) case _ => ; // DO Nothing } } • Note how the list is created. And the pattern matching too Other List Methods • length : Length of list • reverse : Reverse a list • toArray : Convert to array • iterator & next : Iterator protocol • mkString : Concatenate elements into a string • apply : Random element access • init : All but last element in a list • last : Last element in a list Patterns of collection computations • There are some frequently occurring general purpose patterns used over collections. • These are all a part of the scala collections API. • This is one area where you will find a significant expressivity and brevity upgrade over java.
  • 3. map : Applying to each element def double(x: Int) = x * 2 List(1,3,5) map double // OR List(1,3,5) map {n => n * 2} // OR List(1,3,5) map {_ * 2} // All result into List(2, 6, 10) • Note the inline and anonymous function declarations the the parameter "_" Equivalent Java Code public static List<Integer> doubleAll(List<Integer> numbers) { List<Integer> doubled = new LinkedList<Integer>(); for(Integer n : numbers) { doubled.add(n * 2); } return doubled; } public static void main(String[] args) { System.out.println(doubleAll(Arrays.asList(1,3,5))); } Regarding map • In the earlier example, how would you write tripleAll instead of doubleAll? Ans: Copy the entire function and modify slightly. • Map is a very frequently occurring operation on collections • The process of mapping is abstracted away orthogonally from the operation performed on each element • This results in a substantial reduction in size • This also removes a lot of ceremony and boilerplate. Regarding map .. 2 • You focus on the very essence of what is being done eg. myList map double • Stripping away of ceremony & boiler plate, and ability to focus on the essence, is a consistent characteristic of many methods on List & other collections • If you think about it, you will find lots and lots of uses of map in your regular tasks eg. computation of tax on each item in a list • When we pass a function as an argument to a function (or expect a function as a return type), thats termed Higher Order Functions (HOFs). eg. double
  • 4. filter : Selecting elements // select only odd numbers from a list List(1,2,3,4,5) filter { _%2 != 0} // results into List(1, 3, 5) • Again this is a frequently used pattern. Again scala strips away the ceremony and allows you to focus on the essence. (I'll stop repeating this) • Also notice the predicate selecting odd numbers being used as a HOF (I'll stop repeating this too). fold : Summarising / Aggregation (0 /: List(1,2,3,4)) {(sum,num) => sum + num} List(1,2,3,4).foldLeft(0){(sum,num) => sum + num} List(1,2,3,4).foldLeft(0){_ + _} // All result in the value 10 • Yet again, a frequently found pattern. eg. creating total for an invoice Other Patterns • take and takeWhile : Select first few elements of a list • drop and dropWhile : Select last few elements of a list • zip and unzip : Combine two lists into list of pairs (& vice-versa) • partition : Split a list into two based on a predicate • forall and exists : Test all or any one element of a list for a predicate • sortWith : Sort given a comparation predicate • flatten : Flatten a List of List of X into a List of X • flatMap : Flatten a List of List obtained by mapping a function that returns a list Back to iteration over a list Earlier we saw a for loop and a recursive method of traversing a list. One might be tempted to use map to print all elements of a list // Whats the return value ? List(1,2,3,4) map { println _ } // When you are not interested in the return value // interested only in the side effects of the function List(1,2,3,4) foreach { println _ } For Comprehensions Combines for loops, filters, and assignments
  • 5. case class Cell(val row: Int, val col: Int) def isOccupied(c: (Int, Int)) = (c._1 + c._2) % 2 == 0 def findFreeCells(): List[String] = { val p = for(i <- 1 to 3; j <- 1 to 3; cell = (i,j); if (!isOccupied(cell)) ) yield (List(i,j).mkString("C","","")) p toList } Equivalent Java Code class Cell { private Integer row; private Integer col; public Cell(Integer row, Integer col) { this.row = row; this.col = col; } public Integer getRow() { return this.row; } Java code continued... public Integer getCol() { return this.col; } } public static boolean isOccupied(Cell cell) { return ((cell.getRow() + cell.getCol()) % 2) == 0; }
  • 6. Java code continued... public static List<String> findFreeCells() { List<String> retList = new LinkedList<String>(); for(int i = 1 ; i <= 3 ; i++) { for(int j = 1 ; j <= 3 ; j++) { Cell c = new Cell(i,j); if (isOccupied(c) == false) { retList.add("C" + c.getRow() + c.getCol()); } } } return retList; } Aside: Case classes • Case classes are simple java beans like classes. • scala throws in getters / setters / hashCode / toString / equals etc. automatically. • Also quite useful when pattern matching (beyond scope of this talk) • Can also add additional methods case class Cell(val row: Int, val col: Int) { def isOccupied = (row + col) % 2 == 0 } Maps val states = Map("GJ" -> "Gujarat", "MH" -> "Maharashtra", "KL" -> "Kerala") states get "GJ" states("GJ") states("ZZ") // will raise an exception states.getOrElse("ZZ","Unknown") states + ("SK" -> "Sikkim") states - "KL" states filterKeys {_(0) == 'G'} states filter {_._2.length() <= 7} states transform {(key,value) => value.toLowerCase } Other collections • Set (HashSet / TreeSet) : Fairly similar semantics. Few extra eg. intersect, union, diff • Vector : Indexed access, Constant time non head access • Queue • Stack
  • 7. Streams Lazily evaluated. def fibonacci(first: Int, second: Int): Stream[Int] = first #:: fibonacci(second, first + second) val f = fibonacci(1,1) // result = List(1, 1, 2, 3, 5, 8, 13) f.takeWhile {_ < 20} toList Mutable or Immutable • Most collections come in both mutable and immutable variants • (Surprisingly?) the preferred usage is immutable • A detailed discussion on the matter is beyond the scope of the talk • A good java equivalent to immutable classes is String. Think the same design principles applied across the collections. • Just like string, there exist mutable Buffer/Builder classes to slowly collect elements of a collection and finally convert them into an immutable collection. Parallel Collections (1 to 10) foreach {println} (1 to 10).par foreach {println} Sample Code (To be shown separately) package ordersystem import scala.collection.mutable case class CustomerOrder( val orderId: String, val customerCode: String, val productCode: String, val quantity: Int) case class ProductMaster( val productCode: String, val manufacturingTime: Int, val components: List[(String,Int)]) case class ShippingNote( val customerCode: String, val items: List[ShipItem]) case class ShipItem( val customerCode: String, val orderId: String, val productCode: String, val quantity: Int) case class MakeProduct( val customerCode: String, val orderId: String,
  • 8. val productCode: String, val quantity: Int) object OrderSystem { var inventory = mutable.Map("foo" -> 14, "bar" -> 14, "baz" -> 14) val productMaster = List( ProductMaster("foo",5,List(("zoo", 7),("zar",9))), ProductMaster("bar",7,List(("boo", 9),("moo",6))), ProductMaster ("baz",6,List(("zar",4),("moo",5)))) map {p => p.productCode -> p} toMap val itemInventory = mutable.Map("zoo" -> 80, "zar" -> 100, "boo" -> 25, "moo" -> 30) def shipOrMake(order: CustomerOrder) = { // find existing available products in stock val available = inventory.getOrElse(order.productCode,0) // compute products that can be shipped, updated stocks and those that need to be made val (ship, stock, make) = if (order.quantity < available) (order.quantity, available - order.quantity, 0) else (available, 0, order.quantity - available) inventory.put(order.productCode,stock) // create shipment instruction val shipItem = if (ship > 0) Some(ShipItem(order.customerCode, order.orderId, order.productCode, ship)) else None println("Ship:" + shipItem) // and/or make product instruction val makeProduct = if (make > 0) Some(MakeProduct(order.customerCode, order.orderId, order.productCode, make)) else None (shipItem, makeProduct) } def main(args: Array[String]) = { val orders = List( CustomerOrder("c11","c1", "foo", 10), CustomerOrder("c12","c1", "bar", 12), CustomerOrder("c12","c1", "baz", 14), CustomerOrder("c21","c2", "foo", 12), CustomerOrder("c22","c2", "bar", 10), CustomerOrder("c22","c2", "baz", 12)) // find which products to ship directly and which to make val shipMakeProducts = orders map shipOrMake // will give shipitem and makeitem // create ship item notices val shipItems = (shipMakeProducts map {_._1} flatten) groupBy {_.customerCode} map { x => ShippingNote(x._1,x._2) }; println(shipItems) // create make product notices val makeProducts = shipMakeProducts map {_._2} flatten ; println(makeProducts) val todo = makeProducts map { order => // for each product that has to be made // get the corresponding product master println("Processing Make Product Order:" + order) productMaster.get(order.productCode) match { case Some(master) => // for each of the components required master.components map { // compute the quantities of items required pmc => (pmc._1, pmc._2 * order.quantity) } map { requiredPair => val item = requiredPair._1 val itemQuantity = requiredPair._2 // compare with available quantities val available = itemInventory.getOrElse(item,0) // requisition if not available val (used, requisitioned) = if (available >= itemQuantity) { (itemQuantity,0) } else { (available, itemQuantity - available)
  • 9. } itemInventory.put(item,available - used) println("Using " + used + " units of " + item + " and requisitioning " + requisitioned) (item,used,requisitioned) } case None => throw new Exception("product not in product master") } } // flatten the resultant list and group by item code val itemMap = (todo flatten) groupBy {_._1} println(itemMap) // for each item, fold the corresponding list to arrive at cumulative totals val itemMap2 = itemMap map {keyVal => (keyVal._1,((0,0) /: keyVal._2){(total,each) => (total._1 + each._2, total._2 + each._3)}) } println(itemMap2) } } Thank You Contact Information: Dhananjay Nene Vayana Services http://blog.dhananjaynene.com http://twitter.com/dnene firstname dot lastname at gmail dot com