deftime[R](block: => R): R = { val t0 = System.nanoTime() val result = block val t1 = System.nanoTime() println(" Elpased time : " + (t1 - t0) + "ns") println(" Elpased time : " + (t1 - t0) / 1000000 + "ms") result }
ex 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/** * Ex 1: * * Set up a map of prices for a number of gizmos that you covet. Then produce a second map with the same keys and * the prices at a 10 percent discount. * * @return */ privatedefreducedPrices(): Map[String, Int] = { val gizmos = Map("iPhone" -> 600, "iPad" -> 500, "MacBook Pro" -> 2000, "ScalaDays 2016 Berlin" -> 750) gizmos.mapValues(price => price - price / 10) }
privatedefreducedPrices2(): Map[String, Int] = { val gizmos = Map("iPhone" -> 600, "iPad" -> 500, "MacBook Pro" -> 2000, "ScalaDays 2016 Berlin" -> 750) for ((k, v) <- gizmos) yield (k, v - v / 10) }
test :
1 2 3 4
println("test1: mapValues==============") prn(time(reducedPrices())) println("test2: for yield===============") prn(time(reducedPrices2()))
result:
1 2 3 4 5 6 7 8 9
test1: mapValues============== Elpased time : 74032222ns Elpased time : 74ms $anon$2(iPhone -> 540, iPad -> 450, MacBook Pro -> 1800, ScalaDays 2016 Berlin -> 675) test2: for yield=============== Elpased time : 2313363ns Elpased time : 2ms Map4(iPhone -> 540, iPad -> 450, MacBook Pro -> 1800, ScalaDays 2016 Berlin -> 675)
/** * ex 2: * * Write a program that reads words from a file. Use a mutable map to count how often each word appears. To read * the words, simply use a java.util.Scanner: * val in = new java.util.Scanner(new java.io.File("myfile.txt")) while (in.hasNext()) process in.next() * Or look at Chapter 9 for a Scalaesque way. * * @return */ private def countWordsInFile(): mutable.Map[String, Int] = { val words = new mutable.HashMap[String, Int] val in = new Scanner(getClass.getResourceAsStream("/myfile.txt")) try { while (in.hasNext()) { words(in.next()) = words.getOrElse(in.next(), 0) + 1 } } finally { in.close() } words }
/** * Ex 3: * * Repeat the preceding exercise with an immutable map. * * @return */ privatedefcountWordsWithImutableMap() : immutable.Map[String, Int] = { var words = new immutable.HashMap[String, Int] val in = newScanner(getClass.getResourceAsStream("/myfile.txt")) try { while (in.hasNext()) { words += (in.next() -> (words.getOrElse(in.next(), 0) + 1)) } } finally { in.close() } words }
test result:
1 2 3 4 5 6
test3 : mutable map=============== Elpased time : 61550627ns Elpased time : 61ms test4 : immutable map=============== Elpased time : 41690959ns Elpased time : 41ms
/** * ex 4 * * Repeat the preceding exercise with a sorted map, so that the words are printed in sorted order. * * @param */
privatedefcountWordsWithSortedMap(): mutable.SortedMap[String, Int] = { var words = mutable.SortedMap[String, Int]() val in = newScanner(getClass.getResourceAsStream("/myfile.txt")) try { while (in.hasNext()) { words(in.next()) = words.getOrElse(in.next(), 0) + 1 } } finally { in.close() } words }
/** * ex 4 * * Repeat the preceding exercise with a sorted map, so that the words are printed in sorted order. * * @param */
privatedefcountWordsWithImutabeSortedMap(): immutable.SortedMap[String, Int] = { var words = immutable.SortedMap[String, Int]() val in = newScanner(getClass.getResourceAsStream("/myfile.txt")) try { while (in.hasNext()) { words += (in.next() -> (words.getOrElse(in.next(), 0) + 1)) } } finally { in.close() } words }
result:
1 2 3 4 5 6 7
test5 : mutable sorted map=============== Elpased time : 51210905ns Elpased time : 51ms test6: immutable sorted map=============== Elpased time : 48273714ns Elpased time : 48ms
/** * ex 5 * * Repeat the preceding exercise with a tree map, so that the words are printed in sorted order. * * @param */
privatedefcountWordsWithImutabeTreeMap(): immutable.TreeMap[String, Int] = { var words = immutable.TreeMap[String, Int]() val in = newScanner(getClass.getResourceAsStream("/myfile.txt")) try { while (in.hasNext()) { words += (in.next() -> (words.getOrElse(in.next(), 0) + 1)) } } finally { in.close() } words }
/** * ex 5 * * Repeat the preceding exercise with a tree map, so that the words are printed in sorted order. * * @param */
privatedefcountWordsWithTreeMap(): mutable.TreeMap[String, Int] = { var words = mutable.TreeMap[String, Int]() val in = newScanner(getClass.getResourceAsStream("/myfile.txt")) try { while (in.hasNext()) { words(in.next()) = words.getOrElse(in.next(), 0) + 1 } } finally { in.close() } words }
result :
1 2 3 4 5 6 7
test7: mutable tree map=============== Elpased time : 17678666ns Elpased time : 17ms test8: immutable tree map=============== Elpased time : 17895029ns Elpased time : 17ms
there are duplicate code of read files, we can wrap it as a function also
1 2 3 4 5 6 7 8 9 10 11
defprocessWords(process : String => Unit) : Unit = { val in = newScanner(getClass.getResourceAsStream("/myfile.txt")) try { while (in.hasNext()) { process(in.next()) } } finally { in.close() }
}
then rewrite the code like this:
1 2 3 4 5 6 7 8 9 10 11 12
privatedefcountWordsWithImutableMap2() : immutable.Map[String, Int] = { var words = new immutable.HashMap[String, Int] processWords(w => words += w -> (words.getOrElse(w,0) + 1)) words }
privatedefcountWordsInFile2(): mutable.Map[String, Int] = { val words = new mutable.HashMap[String, Int] processWords(w => words(w) = words.getOrElse(w, 0) + 1) words }
/** * ex 6 * * Define a linked hash map that maps "Monday" to java.util.Calendar.MONDAY, and similarly for the other weekdays. * Demonstrate that the elements are visited in insertion order. * * @return */ defweekdaysLinkedHashMap(): mutable.Map[String, Int] = { import java.util.Calendar._ val days = scala.collection.mutable.LinkedHashMap( "MONDAY" -> MONDAY, "TUESDAY" -> TUESDAY, "WEDNESDAY" -> WEDNESDAY, "THURSDAY" -> THURSDAY, "FRIDAY" -> FRIDAY, "SATURDAY" -> SATURDAY, "SUNDAY" -> SUNDAY )
/** * * ex 8 * * Write a function minmax(values: Array[Int]) that returns a pair * containing the smallest and the largest values in the array. * * @param values * @return */ defminmax(values: Array[Int]): (Int, Int) = (values.min, values.max)
ex 9
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/** * ex 9 * * Write a function lteqgt(values: Array[Int], v: Int) that returns a triple containing the * counts of values less than v, equal to v, and greater than v. * * @param values * @param v * @return */ deflteqgt(values: Array[Int], v: Int): (Int, Int, Int) = { (values.count(_ < v), values.count(_ == v), values.count(_ > v)) }