http://www.scala-lang.org/api/current/#package
http://www.slideshare.net/choijeongyeol/scala-for-play
scala cheatsheets
http://docs.scala-lang.org/cheatsheets/
http://www.scala-lang.org/api/current/#package
http://www.slideshare.net/choijeongyeol/scala-for-play
scala cheatsheets
http://docs.scala-lang.org/cheatsheets/
Scala file FAQ: How do I open and read files in Scala?
When you're writing Scala scripts, you often want to read text files. Fortunately it's pretty easy to openand read from a file in Scala. You can just use an approach like this:
import scala.io.Source val filename = "fileopen.scala" for (line <- Source.fromFile(filename).getLines()) { println(line) }
As you can see, this approach uses the scala.io.Source class. Within the for loop I can now access each line of the file using the 'line' object, and in this case I'm printing each line using println.
A variation of this is to add the mkString function to the file-reading portion of that code, like this:
val fileContents = Source.fromFile(filename).getLines.mkString
Another nice file-reading example comes from Bruce Eckel's website:
val fileLines = io.Source.fromFile("Colors.scala").getLines.toList fileLines.foreach(println)
As you can see from that example, you can read an entire text file into a Scala List with what appears to be only one line of source code.
Of course you can generate exceptions when trying to open a file, and if you want to handle your exceptions, you use a syntax similar to the Java try/catch syntax, like this:
import scala.io.Source val filename = "no-such-file.scala" try { for (line <- Source.fromFile(filename).getLines()) { println(line) } } catch { case ex: Exception => println("Bummer, an exception happened.") }
If I change that Exception line to print my exception object, like this:
case ex: Exception => println(ex)
and then run this script again, I can see that this code throws a java.io.FileNotFoundException exception when it fails:
java.io.FileNotFoundException: no-such-file.scala (No such file or directory)
As a result, if I want to catch all the old Java exceptions like I used to, I can write a Scala script like this to catch the Java FileNotFoundException and IOException:
import scala.io.Source import java.io.{FileReader, FileNotFoundException, IOException} val filename = "no-such-file.scala" try { for (line <- Source.fromFile(filename).getLines()) { println(line) } } catch { case ex: FileNotFoundException => println("Couldn't find that file.") case ex: IOException => println("Had an IOException trying to read that file") }
Scala XML FAQ: How do I load an XML URL in Scala? (How do I read/download the contents of an XML URL in Scala?)
To load the contents of an XML URL (web page) in Scala, such as an RSS news feed or RESTful web service, just use the load method of the Scala XML class:
val xml = XML.load("http://www.devdaily.com/rss.xml")
Here's an example of what this looks like in the Scala REPL:
scala> import scala.xml.XML import scala.xml.XML scala> val xml = XML.load("http://www.devdaily.com/rss.xml") xml: scala.xml.Elem = <rss xml:base="http://www.devdaily.com" version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"> <channel> (output goes on for about ten more lines)
Once you have your XML object (an instance of the scala.xml.Elem class), you can search it as usual. Since my RSS feed includes an "item" tag, I can get the number of item tags in the XML contents:
scala> (xml \\ "item").length res5: Int = 10
I can also do things like searching for "title" elements, such as getting the text from the first RSS title element:
scala> val firstTitle = (xml \\ "channel" \ "title") text firstTitle: String = devdaily.com
As you can see, loading the contents of an XML URL in Scala is very easy.
Scala FAQ: How do I load an XML file in Scala? (How do I open and read an XML file in Scala?)
I demonstrated this in my earlier Scala XML - Searching XMLNS namespaces, XPath tutorial, but you can load an XML file in Scala like this:
import scala.xml.XML val xml = XML.loadFile("/Users/al/Projects/Scala/yahoo-weather.xml")
Once you've loaded the file contents like that, you can manipulate them as desired, such as searching the XML using XPath constructs like this:
val temp = (xml \\ "channel" \\ "item" \ "condition" \ "@temp") text
In summary, if you need to load an XML file in Scala, I hope this has been helpful.
Problem: You want to write XML data to a file in a Scala application, such as saving application data or configuration information to a file.
Use the scala.xml.XML.save
method to write a Scala literal to a file. Given this XML literal:
// create an XML variable val portfolio = <portfolio> <stocks> <stock>AAPL</stock> <stock>AMZN</stock> <stock>GOOG</stock> </stocks> <reits> <reit>Super REIT 1</reit> </reits> </portfolio>
write the literal to file with the save
method:
// save the XML to a file scala.xml.XML.save("portfolio.xml", portfolio)
This creates a plain-text file named portfolio.xml in the current directory, containing the XML literal shown.
As with any file-writing code, beware that XML.save
can throw an exception:
scala> scala.xml.XML.save("/foo/bar/baz", portfolio) java.io.FileNotFoundException: /foo/bar/baz (No such file or directory)
The save
method lets you specify other parameters, including the encoding to use, whether or not to write an XML declaration, and whether or not to write a DOCTYPE declaration.
To write the data to a file with encoding information, use this approach:
XML.save("portfolio.xml", portfolio, "UTF-8", true, null)
This results in the following header being added to the file:
<?xml version='1.0' encoding='UTF-8'?>
To add a DOCTYPE to the file, first import the necessary classes:
import scala.xml.dtd.{DocType, PublicID}
Then create a DocType
instance, and save the file with that instance:
val doctype = DocType("html", PublicID("-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"), Nil) XML.save("portfolio.xml", portfolio, "UTF-8", true, doctype)
With this configuration, the following DOCTYPE line is added to the output file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
The scala.xml package also includes a Utility
object with a small collection of useful methods that let you sort node attributes, trim elements, remove comments, and more.
If it’s important that the XML can be easily read by a human being, it’s best to use the PrettyPrinter class to make sure the XML is “human readable.” But because the PrettyPrinter
returns a String
, you’ll need to write it to a file using another method. I have my own FileUtils
class, so the process looks like this:
val portfolio = <portfolio> <stocks> <stock>AAPL</stock><stock>AMZN</stock><stock>GOOG</stock> </stocks> <reits><reit>Super REIT 1</reit></reits> </portfolio> // 80 characters wide, 2 character indentation val prettyPrinter = new scala.xml.PrettyPrinter(80, 2) val prettyXml = prettyPrinter.format(portfolio) FileUtils.save("portfolio.xml", prettyXml)
Problem: You want to dynamically generate XML from your Scala source code, such as creating output for a SOAP web service.
A great feature of Scala’s XML support is that you can interweave XML and regular Scala source code together. This lets you dynamically generate XML from your Scala code.
To create XML with dynamic, embedded data, just put your Scala code in curly braces inside the XML tags, as shown in the following example:
scala> val name = "Bill" name: String = Bill scala> val age = 42 age: Int = 42 scala> val p = <person><name>{name}</name><age>{age}</age></person> p: scala.xml.Elem = <person><name>Bill</name><age>42</age></person>
In this example, the Scala variables name and age are put inside curly braces, inside the XML literals. The variable p
in the REPL results shows that they’re translated to their values (Bill and 42, respectively). Methods and other expressions can be used in the same way.
This ability to weave Scala code and XML together is similar to using a templating system, and is a great way to generate dynamic XML output, including output like an RSS news feed, all forms of business data, or a simple XHTML UL/LI tag combination:
scala> val fruits = List("apple", "banana", "orange") fruits: List[java.lang.String] = List(apple, banana, orange) scala> val ul = <ul>{fruits.map(i => <li>{i}</li>)}</ul> ul: scala.xml.Elem = <ul><li>apple</li><li>banana</li><li>orange</li></ul> scala> println(ul) <ul><li>apple</li><li>banana</li><li>orange</li></ul>
You can use the same technique to generate XHTML <select>
and <option>
tags, such as for a list of states or credit cards options, and any other form of XML data.
As shown in the fruits example, XML literals can contains Scala code in curly braces, and that code can include additional XML literal values, which can contain Scala code. This nesting of Scala and XML can continue to go deeper, as needed.
To explain how this works, let’s look at the code again:
val ul = <ul>{fruits.map(i => <li>{i}</li>)}</ul>
Here’s how this code works:
<ul>
tags.fruits.map
Scala expression.<li>
tags are embedded in the code block passed to the map
method.i
is enclosed in curly braces inside the <li>
tags, where it will be replaced by its values as the map
method executes.If you’ve used XML/HTML templating tools previously, you can appreciate the power of this approach.
The NodeBuffer
class provides another nice way to dynamically build XML. The following example shows how to build a set of <li>
tags as a NodeBuffer
, and then insert those elements into a final <ul>
tag:
scala> val x = new xml.NodeBuffer x: scala.xml.NodeBuffer = ArrayBuffer() scala> x += <li>apple</li> res0: x.type = ArrayBuffer(<li>apple</li>) scala> x += <li>banana</li> res1: x.type = ArrayBuffer(<li>apple</li>, <li>banana</li>) scala> val ul = <ul>{x}</ul> ul: scala.xml.Elem = <ul><li>apple</li><li>banana</li></ul>
NodeBuffer
is a simple convenience class that extends ArrayBuffer[Node]
. It adds one method named &+
that appends the given object to the buffer, and returns a this reference for convenience. This lets you write a “fluent” style of code like this, if you prefer:
val nb = new xml.NodeBuffer val nb2 = nb &+ <li>apple</li> &+ <li>banana</li> &+ <li>cherry</li>
See Recipe 5.9 of the Scala Cookbook, “Supporting a Fluent Style of Programming,” for more information on supporting and using this coding style.
After writing a Java REST (RESTful) client using Apache HttpClient, I turned around and modified that code to be a Scala REST client, also using the Apache HttpClient library.
Here then, without much introduction, is the source code for a Scala REST client example, which demonstrates how to read information from the Yahoo Weather API, which is actually an RSS feed. As a result, this example also demonstrates how to search an XML document for the information you want, using the built-in Scala XML parsing capabilities.
package tests import java.io._ import org.apache.http.HttpEntity import org.apache.http.HttpResponse import org.apache.http.client.ClientProtocolException import org.apache.http.client.HttpClient import org.apache.http.client.methods.HttpGet import org.apache.http.impl.client.DefaultHttpClient import scala.collection.mutable.StringBuilder import scala.xml.XML object ScalaApacheHttpRestClient { def main(args: Array[String]) { // (1) get the content from the yahoo weather api url val content = getRestContent("http://weather.yahooapis.com/forecastrss?p=80020&u=f") // (2) convert it to xml val xml = XML.loadString(content) assert(xml.isInstanceOf[scala.xml.Elem]) // needed? // (3) search the xml for the nodes i want val temp = (xml \\ "channel" \\ "item" \ "condition" \ "@temp") text val text = (xml \\ "channel" \\ "item" \ "condition" \ "@text") text // (4) print the results val currentWeather = format("The current temperature is %s degrees, and the sky is %s.", temp, text.toLowerCase()) println(currentWeather) } /** * Returns the text content from a REST URL. Returns a blank String if there * is a problem. */ def getRestContent(url:String): String = { val httpClient = new DefaultHttpClient() val httpResponse = httpClient.execute(new HttpGet(url)) val entity = httpResponse.getEntity() var content = "" if (entity != null) { val inputStream = entity.getContent() content = io.Source.fromInputStream(inputStream).getLines.mkString inputStream.close } httpClient.getConnectionManager().shutdown() return content } }
As you can see from the main method, the code is pretty simple, only involving a few steps. The getRestContent function does a lot of the dirty work involved in getting the content from a REST URL. (That function can probably be written better, as I'm ignoring a number of exceptions that can happen.)
There is also some magic involved in processing the XML using the Scala XML library. It took me longer to figure out the syntax to search the XML for the nodes I wanted than it did to write the rest of this example, so I'll discuss that Scala XML syntax in another tutorial.
As I mentioned in my earlier Java RESTful client example, there are several other good ways of creating REST clients in Java and Scala, including using the Jersey project, or the Apache CXF project. Those libraries are specifically geared more towards web services and implementing the API of the Java JSRs that describe web services, while the Apache HttpClient library just simplifies the process of creating HTTP clients. Which one you use is up to you, and I hope/plan to write RESTful clients in Scala using each of those libraries.
In trying to keep this short, I'll leave the example and discussion at that. As usual, if you have any questions, comments, or improvements, just leave a note in the comments section below.
Scala JDBC FAQ: How can I use the Java JDBC API in my Scala application?
If you want to use a SQL database with your Scala applications, it's good to know you can still use the traditional Java JDBC programming library to access databases. I just ran a simple JDBC connectionand SQL SELECT test, and everything seems to work just as it does in Java.
Without any further introduction, here's the source code for a complete Scala class (an object, actually) that connects to a MySQL database using nothing but plain old JDBC. In this example I'm connecting to a MySQL database server on my local computer, and then running a SQL SELECT query against theuser
table of the mysql
database:
package jdbc import java.sql.DriverManager import java.sql.Connection /** * A Scala JDBC connection example by Alvin Alexander, * http://alvinalexander.com */ object ScalaJdbcConnectSelect { def main(args: Array[String]) { // connect to the database named "mysql" on the localhost val driver = "com.mysql.jdbc.Driver" val url = "jdbc:mysql://localhost/mysql" val username = "root" val password = "root" // there's probably a better way to do this var connection:Connection = null try { // make the connection Class.forName(driver) connection = DriverManager.getConnection(url, username, password) // create the statement, and run the select query val statement = connection.createStatement() val resultSet = statement.executeQuery("SELECT host, user FROM user") while ( resultSet.next() ) { val host = resultSet.getString("host") val user = resultSet.getString("user") println("host, user = " + host + ", " + user) } } catch { case e => e.printStackTrace } connection.close() } }
As you can see, this Scala JDBC database connection example looks just like Java JDBC, which you can verify from my very old JDBC connection example and JDBC SQL SELECT example.
If you're new to JDBC and the MySQL URL shown above looks weird because I'm accessing the "mysql" database in the MySQL database server, remember that the general MySQL connection URL looks like this:
val url = "jdbc:mysql://hostname/database_name"
and if I was instead connecting to a database named drupal7
, the MySQL URL would look like this instead:
val url = "jdbc:mysql://localhost/drupal7"
Scala FAQ: Can you share some examples of using tuples in Scala?
A Scala tuple is a class that can contain a miscellaneous collection of elements. I like to think of them as a little bag or container you can use to hold things and pass them around.
You create a tuple with the following syntax, enclosing its elements in parentheses. Here's a tuple that contains an Int
and a String
:
val stuff = (42, "fish")
This creates a specific instance of a tuple called a Tuple2
, which we can demonstrate in the REPL:
scala> val stuff = (42, "fish") stuff: (Int, java.lang.String) = (42,fish) scala> stuff.getClass res0: java.lang.Class[_ <: (Int, java.lang.String)] = class scala.Tuple2
A tuple isn't actually a collection; it's a series of classes named Tuple2
, Tuple3
, etc., through Tuple22
. You don't have to worry about that detail, other than knowing that you can have anywhere from two to twenty-two items in a tuple. (And in my opinion, if you have twenty-two miscellaneous items in a bag, you should probably re-think your design.)
You can access tuple elements using an underscore syntax. The first element is accessed with _1
, the second element with _2
, and so on, like this:
scala> val things = ("a", 1, 3.5) things: (java.lang.String, Int, Double) = (a,1,3.5) scala> println(things._1) a scala> println(things._2) 1 scala> println(things._3) 3.5
When referring to a Scala tuple you can also assign names to the elements in the tuple. I like to do this when returning miscellaneous elements from a method. To demonstrate the syntax, let's create a very simple method that returns a tuple:
def getUserInfo = ("Al", 42, 200.0)
Now we can call that method, and assign the tuple results directly to variables, like this:
val(name, age, weight) = getUserInfo
Here's what this looks like in the REPL:
scala> def getUserInfo = ("Al", 42, 200.0) getUserInfo: (java.lang.String, Int, Double) scala> val(name, age, weight) = getUserInfo name: java.lang.String = Al age: Int = 42 weight: Double = 200.0
It's shown in the REPL results, but we'll further confirm that we can indeed access the values by variable name:
scala> name res4: java.lang.String = Al scala> age res5: Int = 42 scala> weight res6: Double = 200.0
That's pretty nice.
In a cool, related feature, if you only want to access some of the elements, you can ignore the others by using an underscore placeholder for the elements you want to ignore. Imagine you want to ignore theweight
in our example:
scala> val(name, age, _) = getUserInfo name: java.lang.String = Al age: Int = 42
Or suppose you want to ignore the age
and weight
:
scala> val(name, _, _) = getUserInfo name: java.lang.String = Al
Again, that's good stuff.
As mentioned, a tuple is not a collection; it doesn't descend from any of the collection traits or classes. However, you can treat it a little bit like a collection by using its productIterator
method.
Here's how you can iterate over the elements in a tuple:
scala> val t = ("Al", 42, 200.0) t: (java.lang.String, Int, Double) = (Al,42,200.0) scala> t.productIterator.foreach(println) Al 42 200.0
The tuple toString
method gives you a nice representation of a tuple:
scala> t.toString res9: java.lang.String = (Al,42,200.0) scala> println(t.toString) (Al,42,200.0)
->
In another cool feature, you can create a tuple using this syntax:
1 -> "a"
This creates a Tuple2
, which we can demonstrate in the REPL:
scala> 1 -> "a" res1: (Int, java.lang.String) = (1,a) scala> res11.getClass res2: java.lang.Class[_ <: (Int, java.lang.String)] = class scala.Tuple2
You'll see this syntax a lot when creating maps:
scala> val map = Map(1->"a", 2->"b") map: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a, 2 -> b)
Scala Map FAQ: How can I iterate/loop over a Scala Map?
There are several different ways to iterate over a Scala Map, and the method you choose depends on the problem you need to solve.
To get started with our examples, let's create a simple Map we can work with:
scala> val m1 = Map("fname" -> "Al", "lname" -> "Alexander")
Once you have a Map, you can iterate over it using several different techniques. For me, this is by far the easiest technique:
scala> for ((k,v) <- m1) printf("key: %s, value: %s\n", k, v) key: fname, value: Al key: lname, value: Alexander
This page has some other Map and for loop examples, which I've reproduced here:
// version 1 (tuples) m1 foreach (x => println (x._1 + "-->" + x._2)) // version 2 (foreach and case) m1 foreach {case (key, value) => println (key + "-->" + value)}
You can choose whatever format you prefer. Scala is beginning to remind me of the Perl slogan: "There's more than one way to do it", and this is good, because you can choose whichever approach makes the most sense for the problem at hand.
To demonstrate a more "real world" example of looping over a Scala Map, while working through some programming examples in the book, Programming Collective Intelligence, I decided to code them up in Scala, and I wanted to share the approaches I prefer using the Scala foreach and for loops.
To begin with, I defined my Scala Map like this:
val p1Ratings = Map("Lady in the Water"-> 3.0, "Snakes on a Plane"-> 4.0, "You, Me and Dupree"-> 3.5)
In my case, when I'm iterating over the Map I'm really just interested in the Map keys, so the cleanest way to loop over every Map element is like this:
p1Ratings.keys.foreach( (movie) => if (p2Ratings.contains(movie)) similarItems += (movie -> true) )
While I chose that looping method in my code, I could also use the "tuples" approach, where movie
is a Tuple, and I only use the first element of the Tuple, which happens to be my keys:
p1Ratings foreach ( (movie) => if (p2Ratings.contains(movie._1)) similarItems += (movie._1 -> true) )
In that approach, I ignore the second element of each Tuple, because I don't need it. (Which is why I don't like this approach for this instance.)
In a similar approach, I loop over the Map as shown next, creating a field named rating1
which I again don't use because I don't need it:
for ((movie1, rating1) <- p1Ratings) { if (p2Ratings.contains(movie1)) similarItems += (movie1 -> true) }
These last two approaches will work better, and look a little more logical, if you need to access the key and value for each map element, but in my case, since I don't need to values, I'm using the first approach shown above.
Here's a quick look at how to use the Scala Map class, with a colllection of Map class examples.
The immutable Map class is in scope by default, so you can create an immutable map without an import, like this:
val states = Map("AL" -> "Alabama", "AK" -> "Alaska")
To create a mutable Map, import it first:
var states = scala.collection.mutable.Map("AL" -> "Alabama")
The following examples show how to add, remove, and update elements in a mutable Scala Map:
// create an empty map var states = scala.collection.mutable.Map[String, String]() // create a map with initial elements var states = scala.collection.mutable.Map("AL" -> "Alabama", "AK" -> "Alaska") // add elements with += states += ("AZ" -> "Arizona") states += ("CO" -> "Colorado", "KY" -> "Kentucky") // remove elements with -= states -= "KY" states -= ("AZ", "CO") // update elements by reassigning them states("AK") = "Alaska, The Big State"
Once you have a Map, you can iterate over it using several different techniques. I prefer using the for loop (or for comprehension):
scala> val m1 = Map("fname" -> "Al", "lname" -> "Alexander") scala> for ((k,v) <- m1) printf("key: %s, value: %s\n", k, v) key: fname, value: Al key: lname, value: Alexander
This page has some other Map and for loop examples, which I've reproduced here:
// version 1 (tuples) m1 foreach (x => println (x._1 + "-->" + x._2)) // version 2 (foreach and case) m1 foreach {case (key, value) => println (key + "-->" + value)}
You can choose whatever format you prefer.
To demonstrate a more "real world" example of looping over a Scala Map, while I was working through some programming examples in the book, Programming Collective Intelligence, I decided to code them up in Scala.
To begin with, I defined my Scala Map like this:
val p1Ratings = Map("Lady in the Water"-> 3.0, "Snakes on a Plane"-> 4.0, "You, Me and Dupree"-> 3.5)
In my case, when I'm iterating over the Map I'm really just interested in the Map keys, so the cleanest way to loop over every Map element is like this:
p1Ratings.keys.foreach( (movie) => if (p2Ratings.contains(movie)) similarItems += (movie -> true) )
While I chose that looping method in my code, I could also use the "tuples" approach, where movie
is a Tuple, and I only use the first element of the Tuple, which happens to be my keys:
p1Ratings foreach ( (movie) => if (p2Ratings.contains(movie._1)) similarItems += (movie._1 -> true) )
In that approach, I ignore the second element of each Tuple, because I don't need it. (Which is why I don't like this approach for this instance.)
In a similar approach, I loop over the Map as shown next, creating a field named rating1
which I again don't use because I don't need it:
for ((movie1, rating1) <- p1Ratings) { if (p2Ratings.contains(movie1)) similarItems += (movie1 -> true) }
These last two approaches will work better, and look a little more logical, if you need to access the key and value for each map element, but in my case, since I don't need to values, I'm using the first approach shown above.
The Scala List class filter method implicitly loops over the List you supply, tests each element of the List with the function you supply. Your function must return true or false, and filter returns the list elements where your function returns true.
(Note: Even though I use a List in these examples, the filter method can be used on any Scala sequence, including Array, List, Vector, Seq, etc.)
Let's look at a few simple examples. In this first example we filter a small list of numbers so that our resulting list only has numbers that are greater than 2:
scala> val nums = List(5, 1, 4, 3, 2) nums: List[Int] = List(5, 1, 4, 3, 2) scala> nums.filter(_ > 2) res0: List[Int] = List(5, 4, 3)
Note that in the real world you'd assign the filtered results to a new List, like this:
val originalList = List(5, 1, 4, 3, 2) val newList = originalList.filter(_ > 2)
This example shows how to get the even numbers from a List using a simple modulus test:
scala> nums.filter( _ % 2 == 0 ) res21: List[Int] = List(4, 2)
You can take that example a step further by filtering and then sorting the list:
# filter and sort scala> nums.filter( _ % 2 == 0 ).sort(_ < _) warning: there were 1 deprecation warnings; re-run with -deprecation for details res22: List[Int] = List(2, 4)
Here are two filter method examples with a list of Strings:
val fruits = List("orange", "peach", "apple", "banana") scala> fruits.filter(_.length > 5) res21: List[java.lang.String] = List(banana, orange) scala> fruits.filter(_.startsWith("a")) res22: List[java.lang.String] = List(apple)
From the excellent book, Beginning Scala, here's a nice combination of the List filter, sort, and map methods:
trait Person { def first: String def age: Int def valid: Boolean } Returns the first name of 'valid' persons, sorted by age def validByAge(in: List[Person]) = in.filter(_.valid). sort(_.age < _.age). map(_.first)
The following example shows how you can use filter
with map
to transform the type of data that the expression returns. In this case we'll start with a sequence of Person
objects, and transform it into a sequence of String
objects.
We'll start with a simple case class:
scala> case class Person(first: String, last: String, mi: String) defined class Person
Next, we'll create a little sequence of Person
objects:
scala> val fred = Person("Fred", "Flintstone", "J") fred: Person = Person(Fred,Flintstone,J) scala> val wilma = Person("Wilma", "Flintstone", "A") wilma: Person = Person(Wilma,Flintstone,A) scala> val barney = Person("Barney", "Rubble", "J") barney: Person = Person(Barney,Rubble,J) scala> val betty = Person("Betty", "Rubble", "A") betty: Person = Person(Betty,Rubble,A) scala> val peeps = Seq(fred, wilma, barney, betty) peeps: Seq[Person] = List(Person(Fred,Flintstone,J), Person(Wilma,Flintstone,A), Person(Barney,Rubble,J), Person(Betty,Rubble,A))
Finally, we'll combine filter
and map
to get a list of all first names where the last name is "Flintstone":
scala> peeps.filter(_.last == "Flintstone").map(_.first) res0: Seq[String] = List(Fred, Wilma)
The way this works is:
filter
method returns a sequence of Person
objects where the last name is "Flintstone".map
method call gets the first name of each Person
object. This results in a sequence of strings, where each string is the first name of each person that came out of the filter
call.I initially wrote this as a for/yield loop, but then realized I could write this much more concisely with this approach. At the moment I find the for/yield loop to be more readable, and this to be much more concise.
In my opinion, this code can be made a little more readable by using a variable name in the map
expression, as a reminder that you're still dealing with Person
objects:
scala> peeps.filter(_.last == "Flintstone").map(person => person.first) res1: Seq[String] = List(Fred, Wilma)
I hope these filter method examples have been helpful. Here's a quick summary of how the filter method works:
Scala List FAQ: Can you share some Scala List class examples?
The Scala List class may be the most commonly used data structure in Scala applications. Therefore, it's very helpful to know how create lists, merge lists, select items from lists, operate on each element in a list, and so on.
In this tutorial, I'll try to share examples of the most common List operations (methods).
The Scala List class (scala.List) holds a sequenced, linear list of items. In a List, each element must be of the same type.
At some point I'll add a class diagram here, but until then, here's a simplified version of the Scala List class hierarchy:
(I need to update this, but this is the Scala class hierarchy, as shown by the current Scala API documentation.
You can create a Scala List object in several different way. Here's the Lisp-style approach to creating a List:
scala> val list = 1 :: 2 :: 3 :: Nil list: List[Int] = List(1, 2, 3)
Here's the Java-style approach to creating a Scala List:
scala> val list = List(1,2,3) x: List[Int] = List(1, 2, 3)
A few notes about these approaches:
If you're mixing types in a List constructor, you may need to manually specify the List type. This example demonstrates that syntax:
scala> val x = List[Number](1, 2.0, 33d, 0x1) x: List[java.lang.Number] = List(1, 2.0, 33.0, 1)
In this example, I'm explicitly saying that I want the values in the List to be saved as the Number type.
You can also create a List with the List's range method:
scala> val x = List.range(1,10) x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
The range function can also take a third argument which serves as a "step" value when creating the List:
scala> val x = List.range(0,10,2) x: List[Int] = List(0, 2, 4, 6, 8)
You can also create a new List with the fill method:
scala> val x = List.fill(3)("foo") x: List[java.lang.String] = List(foo, foo, foo)
Finally, you can create a new List with the tabulate method of the List class. The tabulate method creates a new List whose elements are created according to the function you supply. The book Programming in Scala shows how to create a List using a simple "squares" function:
scala> val x = List.tabulate(5)(n => n * n) x: List[Int] = List(0, 1, 4, 9, 16)
As you can see, that example creates a List of five elements, where the element values are the square of the index of each element (0 becomes 0, 1 becomes 1, 2 becomes 4, 3 becomes 9, and 4 becomes 16).
In summary, you can create a new Scala List with these approaches:
You can prepend items to a Scala List using the :: method:
// create a List scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) // prepend an element to the list scala> val y = 0 :: x y: List[Int] = List(0, 1, 2, 3)
According to the Beginning Scala book (and several other sources), prepending items to a list is a "very fast, constant-time, O(1) operation."
(Again, I recall this approach and syntax from using Lisp many years ago.)
There are at least two ways to merge Scala Lists. First, you can merge two Scala lists using the ::: method of the List class:
scala> val a = List(1,2,3) a: List[Int] = List(1, 2, 3) scala> val b = List(4,5,6) b: List[Int] = List(4, 5, 6) scala> val c = a ::: b c: List[Int] = List(1, 2, 3, 4, 5, 6)
This operation is said to have O(n) speed, where n is the number of elements in the first List.
You can also merge two Scala lists using the List's concat method:
scala> val a = List(1,2,3) a: List[Int] = List(1, 2, 3) scala> val b = List(4,5,6) b: List[Int] = List(4, 5, 6) scala> val c = List.concat(a, b) c: List[Int] = List(1, 2, 3, 4, 5, 6)
A very common way to iterate over Scala lists is with the foreach method. Here's a quote about the foreach method from the book Programming in Scala:
foreach takes a procedure (a function with a result type Unit) as the right operand. It simply applies the procedure to each List element. The result of the operation is again Unit; no list of results is assembled.
Here's a simple example showing how to use the foreach function to print every item in a List:
scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) scala> x.foreach { println } 1 2 3
This next example shows a way to sum all the elements in a list using the foreach method:
scala> var sum = 0 sum: Int = 0 scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) scala> x.foreach(sum += _) scala> println(sum) 6
The Scala for comprehension is not specific to lists, but is an extremely powerful way to operate on lists. Here's a simple example of how to iterate over a list using the for comprehension:
scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim") names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim) scala> for (name <- names) println(name) Bob Fred Joe Julia Kim
So far, so good. Now let's add a simple "if" clause to the for comprehension to print only the elements we want to print:
scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim") names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim) scala> for (name <- names if name.startsWith("J")) | println(name) Joe Julia
If you already know about the for comprehension, you know that you can add multiple if clauses, and much more functionality. I could easily write an entire tutorial on the Scala for comprehension, so to keep this tutorial short, I'll stop here for now.
Before leaving, I will add these notes however, from the book Programming in Scala:
Scala provides the for comprehension, which provides syntactically pleasing nesting of map, flatMap, and filter ... The for comprehension is not a looping construct, but is a syntactic construct the compiler reduces to map, flatMap, and filter.
A great thing about Scala is that it is a functional programming language. In the next examples we'll show some of the power of functional programming. In this section we'll focus on the filter method of the List class.
scala> val x = List(1,2,3,4,5,6,7,8,9,10) x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // create a list of all the even numbers in the list scala> val evens = x.filter(a => a % 2 == 0) evens: List[Int] = List(2, 4, 6, 8, 10)
takeWhile
scala> val x = List(1,2,3,4,5,6,7,8,9,10) x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) scala> val y = x.takeWhile(a => a < 6) y: List[Int] = List(1, 2, 3, 4, 5)
Other list filtering methods:
partition - returns a pair of lists, one where the predicate is true, the other where the predicate is false find - returns the first element matching a predicate (as opposed to returning all such elements) Others: takeWhile, dropWhile, span
The Scala List map function "transforms each element of a collection based on a function."
Here are a few map examples. First, doubling every item in a List:
scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) scala> val y = x.map(a => a * 2) y: List[Int] = List(2, 4, 6)
Here's a slightly simpler version of that map example, using the Scala wildcard character (_) instead of a fake variable name:
scala> val y = x.map(_ * 2) y: List[Int] = List(2, 4, 6)
Here's an example using a list of strings:
scala> val names = List("Fred", "Joe", "Bob") names: List[java.lang.String] = List(Fred, Joe, Bob) scala> val lower = names.map(_.toLowerCase) lower: List[java.lang.String] = List(fred, joe, bob) scala> val upper = names.map(_.toUpperCase) upper: List[java.lang.String] = List(FRED, JOE, BOB)
A very nice example in the book Beginning Scala demonstrates how to convert a List into something useful in the HTML world, a list of <li> elements using the map function:
scala> val names = List("Fred", "Joe", "Bob") names: List[java.lang.String] = List(Fred, Joe, Bob) scala> val li = names.map(name => <li>{name}</li>) li: List[scala.xml.Elem] = List(<li>Fred</li>, <li>Joe</li>, <li>Bob</li>)
As you can see, you can rapidly build a lot of functionality in just a little bit of code.
I need to research why this code is deprecated, but for the time being, here's an example of how to sort a Scala List:
scala> val x = List(10, 2, 5) x: List[Int] = List(10, 2, 5) scala> val y = x.sort(_ < _) warning: there were 1 deprecation warnings; re-run with -deprecation for details y: List[Int] = List(2, 5, 10)
(TODO: Research the correct, current approach for sorting Scala lists.)
You can use the List class with the Scala pattern matching and case/match syntax. I'll add examples here as I create them in my own code. (TODO)
The Scala List class has an incredible number of functions/methods, and over time I'll attempt to document them all. In the meantime, here's a short list of the many other Scala List methods I don't have examples for at this time:
length - returns the length of a List head - returns the first element of a List last - returns the last element of a List init - returns a List consisting of all elements except the last one tail - returns every elements of a List except the first element isEmpty - returns a Boolean indicating if the List is empty reverse - returns a reversed version of the List flatten - takes a list of lists and flattens it out to a single list mkString - converts a List to a String iterator toArray foldLeft reduceLeft map flatMap foreach forall exists Folding lists: /: and :\ sortWith
Again, I'll try to add examples of these List methods over time. (TODO)
There are times you may want to use one of the relatives of the Scala List class, instead of using the List class itself. I'll add more to this over time, but for now, here are a few links:
Scala List class FAQ: How do I create a List inScala?
You can create a Scala List in several different ways, including these approaches:
In this Scala List tutorial, I'll demonstrate each of these approaches. I'll execute each command in the Scala command-line interpreter so you can see the results of each approach.
First, if you prefer the Lisp-style of programming, you can create a Scala List using the "cons" syntax, like this:
scala> val list = 1 :: 2 :: 3 :: Nil list: List[Int] = List(1, 2, 3)
As you can see, this creates a List that contains the Ints 1, 2, and 3. With this approach, you need to end the list with the Nil object.
In this "cons" style, the :: method takes two arguments, a "head", which is a single element, and a "tail", which is a List. (And yes, "::" is a function/method.)
My guess is that the most popular way to create a List is with what I call the "Java style":
scala> val list = List(1,2,3) x: List[Int] = List(1, 2, 3)
This syntax looks a lot like the Java way to create an object, except (a) you don't need the "new" keyword before the List, and (b) you don't have to declare the type of elements in the List.
Note that if you're going to mix types in a List constructor, you may need to manually specify the type of the List. This example demonstrates the syntax to specify the List type:
scala> val x = List[Number](1, 2.0, 33d, 0x1) x: List[java.lang.Number] = List(1, 2.0, 33.0, 1)
In this example I've explicitly stated that the values in the List are of the Number type.
Another convenient way to create a List is with the List class range method:
scala> val x = List.range(1, 10) x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
As you can see, this example created a List of Int values, beginning at 1, and ending at 9.
In addition to this simple approach, the range function can also take a third argument, which serves as a "step" value when creating the List:
scala> val x = List.range(0, 10, 2) x: List[Int] = List(0, 2, 4, 6, 8)
Another convenient way to create a Scala List is with the List class fill method:
scala> val x = List.fill(3)("foo") x: List[java.lang.String] = List(foo, foo, foo)
As you can see, you just specify how many items you want, and the object value you want to fill each List element with.
Finally, you can create a Scala List with the tabulate method of the List class.
The tabulate method creates a new List whose elements are created according to the function you supply. The excellent book "Programming in Scala" shows how to create a List using a simple "squares" function with the tabulate method:
scala> val x = List.tabulate(5)(n => n * n) x: List[Int] = List(0, 1, 4, 9, 16)
As you can see, that example creates a List of five elements, where the element values are the square of the index of each element, so 0 becomes 0, 1 becomes 1, 2 becomes 4, 3 becomes 9, and 4 becomes 16.
In summary, as you have seen, you can create Scala lists in several different ways, including these approaches:
I hope this Scala List class tutorial has been helpful.
Scala List FAQ: How do I merge Scala Lists?
There are at least three ways to merge/concatenate Scala List instances, as shown in the examples below.
First, you can merge two Scala lists using the ::: method of the List class, as demonstrated here at theScala command prompt:
scala> val a = List(1,2,3) a: List[Int] = List(1, 2, 3) scala> val b = List(4,5,6) b: List[Int] = List(4, 5, 6) scala> val c = a ::: b c: List[Int] = List(1, 2, 3, 4, 5, 6)
This operation is said to have O(n) speed, where n is the number of elements in the first List.
You can also merge two Scala lists using the List class concat method:
scala> val a = List(1,2,3) a: List[Int] = List(1, 2, 3) scala> val b = List(4,5,6) b: List[Int] = List(4, 5, 6) scala> val c = List.concat(a, b) c: List[Int] = List(1, 2, 3, 4, 5, 6)
You can also use the List ++ method to concatenate Scala Lists, as shown here:
scala> val a = List(1,2,3) a: List[Int] = List(1, 2, 3) scala> val b = List(4,5,6) b: List[Int] = List(4, 5, 6) scala> val c = a ++ b c: List[Int] = List(1, 2, 3, 4, 5, 6)
I'll try to add more information on these three approaches as I learn about them, but for now, I just wanted to share these three approaches.
Scala List/foreach FAQ: How do I iterate over a Scala List using the foreach method and for loop?
There are a number of ways to iterate over a Scala List using the foreach operator and for comprehension, and I'll show a few of those approaches here.
A common way to iterate over a Scala List is with the foreach method. Here's a quote about the foreach method from the book Programming in Scala:
foreach takes a procedure (a function with a result type Unit) as the right operand. It simply applies the procedure to each List element. The result of the operation is again Unit; no list of results is assembled.
Here's a simple example showing how to use the foreach function to print every item in a List:
scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) scala> x.foreach { println } 1 2 3
If you've used a programming language like Ruby, this syntax will look very familiar to you.
This next example shows a way to sum all the elements in a list using the foreach method:
scala> var sum = 0 sum: Int = 0 scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) scala> x.foreach(sum += _) scala> println(sum) 6
The Scala for comprehension is not specific to lists, but is an extremely powerful way to operate on lists. Here's a simple example of how to iterate over a list using the for comprehension:
scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim") names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim) scala> for (name <- names) println(name) Bob Fred Joe Julia Kim
So far, so good. Now let's add a simple "if" clause to the for comprehension to print only the elements we want to print:
scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim") names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim) scala> for (name <- names if name.startsWith("J")) | println(name) Joe Julia
If you already know about the for comprehension, you know that you can add multiple if clauses, and much more functionality. I could easily write an entire tutorial on the Scala for comprehension, so to keep this tutorial short, I'll stop here for now.
Before leaving, I will add these notes however, from the book Programming in Scala:
Scala provides the for comprehension, which provides syntactically pleasing nesting of map, flatMap, and filter ... The for comprehension is not a looping construct, but is a syntactic construct the compiler reduces to map, flatMap, and filter.
Scala collections FAQ: How can I convert a Scala array to a String?
A simple way to convert a Scala array to a String is with the mkString method of the Array class. (Although I've written "array", the same technique also works with any Scala sequence, including Array, List, Seq, ArrayBuffer, Vector, and other sequence types.)
Here's a quick array to string example using the Scala REPL:
scala> val args = Array("Hello", "world", "it's", "me") args: Array[java.lang.String] = Array(Hello, world, it's, me) scala> val string = args.mkString(" ") string: String = Hello world it's me
In this first statement:
val args = Array("Hello", "world", "it's", "me")
I create a Scala array named args, and in this second statement:
val string = args.mkString(" ")
I create a new String variable named string, separating each String in the array with a space character, which I specified when calling the mkString function.
Note that I could have given the mkString function any String to use as a separating character, like this:
scala> val string = args.mkString("\n") string: String = Hello world it's me
or like this:
scala> val string = args.mkString(" . ") string: String = Hello . world . it's . me
As a final example, you can also use the Scala mkString method to convert an Int array to a String, like this:
scala> val numbers = Array(1,2,3) numbers: Array[Int] = Array(1, 2, 3) scala> val string = numbers.mkString(", ") string: String = 1, 2, 3
In summary, I hope these Scala "Array to String" examples have been helpful.
Scala Map FAQ: How can I iterate/loop over a Scala Map?
There are several different ways to iterate over a Scala Map, and the method you choose depends on the problem you need to solve.
To get started with our examples, let's create a simple Map we can work with:
scala> val m1 = Map("fname" -> "Al", "lname" -> "Alexander")
Once you have a Map, you can iterate over it using several different techniques. For me, this is by far the easiest technique:
scala> for ((k,v) <- m1) printf("key: %s, value: %s\n", k, v) key: fname, value: Al key: lname, value: Alexander
This page has some other Map and for loop examples, which I've reproduced here:
// version 1 (tuples) m1 foreach (x => println (x._1 + "-->" + x._2)) // version 2 (foreach and case) m1 foreach {case (key, value) => println (key + "-->" + value)}
You can choose whatever format you prefer. Scala is beginning to remind me of the Perl slogan: "There's more than one way to do it", and this is good, because you can choose whichever approach makes the most sense for the problem at hand.
To demonstrate a more "real world" example of looping over a Scala Map, while working through some programming examples in the book, Programming Collective Intelligence, I decided to code them up in Scala, and I wanted to share the approaches I prefer using the Scala foreach and for loops.
To begin with, I defined my Scala Map like this:
val p1Ratings = Map("Lady in the Water"-> 3.0, "Snakes on a Plane"-> 4.0, "You, Me and Dupree"-> 3.5)
In my case, when I'm iterating over the Map I'm really just interested in the Map keys, so the cleanest way to loop over every Map element is like this:
p1Ratings.keys.foreach( (movie) => if (p2Ratings.contains(movie)) similarItems += (movie -> true) )
While I chose that looping method in my code, I could also use the "tuples" approach, where movie
is a Tuple, and I only use the first element of the Tuple, which happens to be my keys:
p1Ratings foreach ( (movie) => if (p2Ratings.contains(movie._1)) similarItems += (movie._1 -> true) )
In that approach, I ignore the second element of each Tuple, because I don't need it. (Which is why I don't like this approach for this instance.)
In a similar approach, I loop over the Map as shown next, creating a field named rating1
which I again don't use because I don't need it:
for ((movie1, rating1) <- p1Ratings) { if (p2Ratings.contains(movie1)) similarItems += (movie1 -> true) }
These last two approaches will work better, and look a little more logical, if you need to access the key and value for each map element, but in my case, since I don't need to values, I'm using the first approach shown above.
Scala List/foreach FAQ: How do I iterate over a Scala List using the foreach method and for loop?
There are a number of ways to iterate over a Scala List using the foreach operator and for comprehension, and I'll show a few of those approaches here.
A common way to iterate over a Scala List is with the foreach method. Here's a quote about the foreach method from the book Programming in Scala:
foreach takes a procedure (a function with a result type Unit) as the right operand. It simply applies the procedure to each List element. The result of the operation is again Unit; no list of results is assembled.
Here's a simple example showing how to use the foreach function to print every item in a List:
scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) scala> x.foreach { println } 1 2 3
If you've used a programming language like Ruby, this syntax will look very familiar to you.
This next example shows a way to sum all the elements in a list using the foreach method:
scala> var sum = 0 sum: Int = 0 scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) scala> x.foreach(sum += _) scala> println(sum) 6
The Scala for comprehension is not specific to lists, but is an extremely powerful way to operate on lists. Here's a simple example of how to iterate over a list using the for comprehension:
scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim") names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim) scala> for (name <- names) println(name) Bob Fred Joe Julia Kim
So far, so good. Now let's add a simple "if" clause to the for comprehension to print only the elements we want to print:
scala> val names = List("Bob", "Fred", "Joe", "Julia", "Kim") names: List[java.lang.String] = List(Bob, Fred, Joe, Julia, Kim) scala> for (name <- names if name.startsWith("J")) | println(name) Joe Julia
If you already know about the for comprehension, you know that you can add multiple if clauses, and much more functionality. I could easily write an entire tutorial on the Scala for comprehension, so to keep this tutorial short, I'll stop here for now.
Here's a quick look at how to create a multi-dimensional array in Scala, in this case a 2D array (matrix), and then access the array elements. As you can see, these commands were issued using the Scala REPL, and I've added a few comments to them:
// create a 2D array scala> val matrix = Array.ofDim[Int](2,2) matrix: Array[Array[Int]] = Array(Array(0, 0), Array(0, 0)) // populate the array elements scala> matrix(0)(0) = 0 scala> matrix(0)(1) = 1 scala> matrix(1)(0) = 2 scala> matrix(1)(1) = 3 // access a couple of array elements scala> matrix(0)(1) res4: Int = 1 scala> matrix(1)(0) res5: Int = 2
If you ever need to create a multidimensional array in Scala, I hope this example is helpful.
While working on a new Scala application, I just ran into a situation where a Java class I was using returned a Java List to me. I wasn't exactly thinking too hard at that moment, and didn't realize it was actually a Java List until I tried to use the foreach method on it, and Eclipse balked at me.
Suddenly I ran into a common problem in Scala: When you're using Java classes from Scalaapplications, those Java class will return Java collections. You can then either use them as the Java collections that they are (such as using a Java Iterator), or cast them to Scala collections.
Amazingly, to use methods like foreach, map, filter, find, and so on with my Java List, all I had to do was add this one import statement to my Scala application:
import scala.collection.JavaConversions._
Once I did that, I could suddenly use a foreach method on my List.
Let's take a quick look at how this works with the Scala command line tool (the Scala REPL). First, we'll create a java.util.List as normal, and see what the REPL shows:
scala> var list = new java.util.ArrayList[Int]() list: java.util.ArrayList[Int] = [] scala> list.add(1) res1: Boolean = true scala> list.add(2) res2: Boolean = true
Now, if I try to use the foreach method on the Java list, it will fail, as expected:
scala> list.foreach <console>:9: error: value foreach is not a member of java.util.ArrayList[Int] list.foreach ^
However, if I now add the magic JavaConversions import statement to my Scala code:
import scala.collection.JavaConversions._
I can then "magically" use the foreach method on my Java List object:
list.foreach { i => println(i) } 1 2
I just started learning Scala in 2011, and it looks like programmers long before me realized the need for the Java to Scala collection conversions, and added this functionality in Scala 2.8. I haven't dug into the source code behind the scenes to see how this magic works, but I just found a nice discussion of the background at the Graham Hacking Scala website.
Graham mentions several interesting points in that article, including these notes:
If we look a bit further into the Scala API, we'll see that there's also a trait called Seq, which is a slightly better parallel to Java's List than the Iterable or Traversable traits. So what you really want to end up with when you bring your Java List into your Scala code is a Scala Seq, not a Scala List.
While I'm on this topic, I'll conclude with a few links to the Scala website, where you can find more information:
As you can see from that second link, the JavaConversions object currently supports the following Java to Scala collections conversions:
scala.collection.Iterable <=> java.lang.Iterable scala.collection.Iterable <=> java.util.Collection scala.collection.Iterator <=> java.util.{ Iterator, Enumeration } scala.collection.mutable.Buffer <=> java.util.List scala.collection.mutable.Set <=> java.util.Set scala.collection.mutable.Map <=> java.util.{ Map, Dictionary } scala.collection.mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap
Important for my current project, the following one-way conversions are also offered:
scala.collection.Seq => java.util.List scala.collection.mutable.Seq => java.util.List scala.collection.Set => java.util.Set scala.collection.Map => java.util.Map java.util.Properties => scala.collection.mutable.Map[String, String]
In summary, I hope this brief tutorial on converting Java collections, such as a List, to Scala collections, has been helpful.
Scala FAQ: What are the Scala data types? How many bits do they use to store their data, and what is the range of those data types?
Courtesy of the excellent book, Programming in Scala, here is a list and description of the Scala data types, including bit sizes and data ranges:
Data Type Definition Boolean true or false Byte 8-bit signed two's complement integer (-2^7 to 2^7-1, inclusive) Short 16-bit signed two's complement integer (-2^15 to 2^15-1, inclusive) Int 32-bit two's complement integer (-2^31 to 2^31-1, inclusive) Long 64-bit two's complement integer (-2^63 to 2^63-1, inclusive) Float 32-bit IEEE 754 single-precision float Double 64-bit IEEE 754 double-precision float Char 16-bit unsigned Unicode character (0 to 2^16-1, inclusive) String a sequence of Chars
The String class resides in the package java.lang
, and all these other types are in the package scala
.
You may have noticed that these data types in Scala have the exact same range as the corresponding data types in Java. This makes it easy to convert these Scala types to their corresponding Java primitive types.
Also interesting to note, if you're into specifics: Collectively, Byte, Short, Int, Long, and Char are calledintegral types. The integral types plus Float and Double are called numeric types. (That was again courtesy of the book, Programming in Scala.)
Here are links to the official Scala docs for these data types:
And here's a link to the Programming in Scala book on Amazon:
Scala collections FAQ: How can I convert a Scala array to a String?
A simple way to convert a Scala array to a String is with the mkString method of the Array class. (Although I've written "array", the same technique also works with any Scala sequence, including Array, List, Seq, ArrayBuffer, Vector, and other sequence types.)
Here's a quick array to string example using the Scala REPL:
scala> val args = Array("Hello", "world", "it's", "me") args: Array[java.lang.String] = Array(Hello, world, it's, me) scala> val string = args.mkString(" ") string: String = Hello world it's me
In this first statement:
val args = Array("Hello", "world", "it's", "me")
I create a Scala array named args, and in this second statement:
val string = args.mkString(" ")
I create a new String variable named string, separating each String in the array with a space character, which I specified when calling the mkString function.
Note that I could have given the mkString function any String to use as a separating character, like this:
scala> val string = args.mkString("\n") string: String = Hello world it's me
or like this:
scala> val string = args.mkString(" . ") string: String = Hello . world . it's . me
As a final example, you can also use the Scala mkString method to convert an Int array to a String, like this:
scala> val numbers = Array(1,2,3) numbers: Array[Int] = Array(1, 2, 3) scala> val string = numbers.mkString(", ") string: String = 1, 2, 3
In summary, I hope these Scala "Array to String" examples have been helpful.
Scala array FAQ: How do I create a String array in Scala?
There are a few different ways to create String arrays in Scala. If you know all your array elements initially, you can create a Scala string array like this:
val fruits = Array("Apple", "Banana", "Orange")
If you don't know the strings that you want in your array initially, but know the size of your array, you can create it first, then populate it later, like this:
val fruits = new Array[String](3) // somewhere later in the code ... fruits(0) = "Apple" fruits(1) = "Banana" fruits(2) = "Orange"
Note that if you want to create a mutable Scala String array, you really want to use the Scala ArrayBufferclass instead of the Array class, like this:
import scala.collection.mutable.ArrayBuffer var fruits = ArrayBuffer[String]() fruits += "Apple" fruits += "Banana" fruits += "Orange"
See my Mutable Scala arrays (adding elements to arrays) tutorial for more information on using the Scala ArrayBuffer.
I can add more Scala String array syntax examples over time, but for now, those are the two most common approaches I know.
Just a quick note today that if you want to create a mutable Scala array -- particularly an array that can grow in size after you first declare it -- you need to use the Scala ArrayBuffer class instead of the Array class, which can't grow.
Here's a short example of how to instantiate an ArrayBuffer object, then add elements to the array:
import scala.collection.mutable.ArrayBuffer var fruits = ArrayBuffer[String]() fruits += "Apple" fruits += "Banana" fruits += "Orange"
Once you have an ArrayBuffer object, you can generally use it like an Array, getting elements like this:
println(fruits(0))
getting the array length like this:
println(fruits.length)
and so on.
Again, the only trick here is knowing that you can't add elements to a Scala array, and therefore, if you want to grow an array, you need to use the ArrayBuffer class instead.
Sometimes when you're writing Scala code, you need to create a null variable (a var, not a val), such as when you need to declare a variable right before using it in a try, catch, finally block. I just ran into this when writing a Scala IMAP email client, where I needed to create two variables right before the trydeclaration, so I could reference the fields in the try block and also in the finally block.
The way you declare a null var variable in Scala is like this:
var store: Store = null var inbox: Folder = null
As you can see from that code, the secret is knowing that you have to assign the type to the variable when you declare it. If you don't do this, Scala won't know the data type of the variable, so it won't allow you to do this, but if you do it, Scala will be happy.
As for my specific problem -- needing to declare a Scala variable right before a try/catch/finally clause -- here's what the solution looks like:
// (1) declare the null variables var store: Store = null var inbox: Folder = null try { // (2) use the variables/fields in the try block store = session.getStore("imaps") inbox = getFolder(store, "INBOX") // rest of the code here ... catch { case e: NoSuchProviderException => e.printStackTrace() System.exit(1) case me: MessagingException => me.printStackTrace() System.exit(2) } finally { // (3) use the variables/fields in the finally clause inbox.close store.close }
In summary, I hope this short example of how to declare an empty/null variable before a try/catch block in Scala has been helpful.
Scala FAQ: Can you share some examples of the Scala try/catch/finally syntax? Also, can you show how to catch multiple exceptions, and just one exception with the Scala wildcard operator (_)?
The general Scala try/catch/finally syntax looks like this:
try { // your scala code here } catch { case foo: FooException => handleFooException(foo) case bar: BarException => handleBarException(bar) case _ => println("Got some other kind of exception") } finally { // your scala code here, such as to close a database connection }
As you can see, the Scala try-catch-finally syntax is similar to the Java try-catch-finally syntax, except for the catch area, which uses Scala's pattern matching capabilities to handle the different exceptions you might run into.
In that example, I'm intentionally catching a FooException and a BarException, and then I'm using the Scala "_" wildcard operator to catch any other exceptions that might occur.
One drawback of using Scala's wildcard character (_) in a catch clause is that you can't refer to it in your code, such as if you want to print the exception.
In the excellent book, Programmming Scala, the authors suggest naming your exception variable instead of using the wildcard, which you can then refer to in your own code, something like this:
try { // your scala code here } catch { case foo: FooException => handleFooException(foo) case bar: BarException => handleBarException(bar) // handling any other exception that might come up case unknown => println("Got this unknown exception: " + unknown) } finally { // your scala code here, such as to close a database connection }
As you can see from that code, I just name a variable "unknown", which I can then refer to by name.
Finally, here's another Scala try/catch example, where I demonstrate how to print the stack trace from an exception:
def runAppleScriptCommand(c: AppleScriptCommand) { val scriptEngineManager = new ScriptEngineManager val appleScriptEngine = scriptEngineManager.getEngineByName("AppleScript") try { appleScriptEngine.eval(c.command) } catch { case e: ScriptException => e.printStackTrace } }
I hope these examples of the Scala try/catch/finally syntax have been helpful. As usual, if you have any questions, comments, corrections, or better examples, just leave a note in the comments section below.
I haven't had the need for this syntax yet, but I just saw some code that shows how to create a private primary constructor in Scala, and I thought I'd test it and share an example of it.
In the example below, I've made the primary constructor of the Order class private:
object PrivateConstructorTests { def main(args: Array[String]) { val o = new Order // this won't compile } } // note the 'private' keyword here class Order private() { def this(orderId: Long) { this(); // more code here ... } }
The primary constructor is made private in this unusual looking line of code:
class Order private() {
This syntax might make a little more sense if I show a primary constructor that takes a parameter:
class Order private(customerId: Long) {
In either case, the "private" keyword in the location shown makes the primary constructor private.
Getting back to the first source code example, as you saw from the comment included in the source code, this line of code won't even compile because the primary constructor is private:
val o = new Order // this won't compile
Again, I haven't had a need to use this Scala "private constructor" syntax yet, but I used to use it in Java when I wanted to enforce the Singleton Pattern, as is done in the Java Calendar class.
Scala offers a cool feature where you can rename a class when you import it, including both Scala and Java classes. The basic syntax to rename a class on import looks like this:
import scala.collection.mutable.{Map => MMap}
and this:
import java.util.{HashMap => JavaMap}
If all you needed to know, I hope those "rename on import" syntax examples were helpful.
An interesting question is, "Why would I want to rename a class on import?"
I've found that I do it to avoid namespace collisions, and/or to make things more clear. For instance, inScala the immutable Map class is imported by default, and if you want to use the mutable version you have to import it manually, as shown here:
# using Map w/o an import gives you an immutable Map scala> val m = Map("name" -> "Al") m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> Al) scala> import scala.collection.mutable.Map import scala.collection.mutable.Map # after the import, the same syntax gives you a mutable Map scala> val m = Map("name" -> "Al") m: scala.collection.mutable.Map[java.lang.String,java.lang.String] = Map(name -> Al)
This can seem confusing, so one way to work around this confusion -- and make your code more obvious -- is to rename the mutable Map class when you import it. Here's a similar example, but in this case I rename the mutable Map class when I import it:
# at first i get an immutable Map scala> val m = Map("name" -> "Al") m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> Al) # i rename the mutable Map class when i import it scala> import scala.collection.mutable.{Map => MMap} import scala.collection.mutable.{Map=>MMap} # here i still get an immutable Map scala> val m = Map("name" -> "Al") m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> Al) # but here i get a mutable Map by referring to MMap scala> val m = MMap("name" -> "Al") m: scala.collection.mutable.Map[java.lang.String,java.lang.String] = Map(name -> Al)
I personally like this approach, because again it makes the code more obvious. You could correctly argue that I could have made it even more obvious if I renamed the class to MutableMap, but in this case I opted for brevity.
There are many more ways you can use this ability to rename classes when you import them in Scala, and if you have a good example you'd like to share, just leave a note below. Until then, reporting live from Boulder, Colorado, this is Alvin Alexander.
In Java, you sometimes refer to .class in your source code, like this:
info = new DataLine.Info(TargetDataLine.class, null);
As you can see, I refer to TargetDataLine.class in this code. This works fine in Java, but if you've tried it in Scala, you know the .class part of that code won't work.
In Scala, if you want to use ".class", you instead need to use the classOf function: The following Scala classOf code is equivalent to the previous Java .class code:
val info = new DataLine.Info(classOf[TargetDataLine], null)
In summary:
In Java, use Foo.class In Scala, use classOf[Foo]
I won't take any time to discuss this today, but if you're interested in a little more information, here's the output from a short Scala REPL session that shows how to use getClass and classOf:
scala> val s = "Foo" s: java.lang.String = Foo scala> s.getClass res7: java.lang.Class[_ <: java.lang.String] = class java.lang.String scala> s.getClass.toString res8: java.lang.String = class java.lang.String scala> classOf[String] res9: java.lang.Class[String] = class java.lang.String