Scala – Tuples & Lists

A Tuple is a generalization of a collection of two, three, four, and more values. Each value can have its own type.

scala> val twoInts = (5,10)
	twoInts: (Int, Int) = (5,10)
scala> val twoStrings = ("Hello", "World")
	twoStrings: (String, String) = (Hello,World)
scala> val threeDoubles = (1.11, 2.22, 3.33)
	threeDoubles: (Double, Double, Double) = (1.11,2.22,3.33)
scala> val intAndString = (1, "Good Evening")
	intAndString: (Int, String) = (1,Good Evening)
scala> val mixedUp = (1, "Vinay Chauhan", 90.50)
	mixedUp: (Int, String, Double) = (1,Vinay Chauhan,90.5)

The elements of a Tuple can be recovered in a few different ways. One way is to use a Tuple when initializing some variables, each of which takes on the value of the corresponding position in the Tuple on the right side of the equal sign.

scala> var (firstInt,secondInt) = twoInts
	firstInt: Int = 5
	secondInt: Int = 10

scala> firstInt
	res39: Int = 5	

Similarly, we could do the actvity for other tuples. 

scala> var (rollNo,name,marks) = mixedUp
	rollNo: Int = 1
	name: String = Vinay Chauhan
	marks: Double = 90.5

scala> rollNo
	res41: Int = 1

scala> name
	res42: String = Vinay Chauhan

scala> marks
	res43: Double = 90.5

Few Tips
Another way to access the values in a Tuple is via indexation, using “_n” where n is the index of the item you want.

scala> print(mixedUp._1)
scala> print(mixedUp._2)
	Vipin Chauhan
scala> print(mixedUp._3)

Few Tips
An alternate form of creating a 2-sized tuple is with the relation operator (->). This is a popular shortcut for representing key-value pairs in tuples:	

scala> val fruitData = "FruitKing" -> "Mango"
	fruitData: (String, String) = (FruitKing,Mango)

scala> fruitData._1
	res3: String = FruitKing

scala> fruitData._2
	res4: String = Mango

Lists are collections of ordered items that will be familiar to anyone who has done any shopping. Tuples are obviously related to lists, but they are less versatile in that they must be created in a single statement, they have a bounded length (about 20 or so), and they don’t support operations that perform computations on all of their elements. In Scala, we can create lists of Strings, Ints, and Doubles (and more).

scala> val fruitList = List("Mango","Orange","PineApple")
	fruitList: List[String] = List(Mango, Orange, PineApple))

scala> fruitList.head
	res0: String = Mango

scala> fruitList.tail
	res2: List[String] = List(Orange, PineApple)

scala> fruitList
	res3: List[String] = List(Mango, Orange, PineApple)

scala> fruitList(1)
	res4: String = Orange

scala> fruitList(2)
	res5: String = PineApple

scala> for(data <- fruitList) println(data) Mango Orange PineApple scala> val oddList = List(1,3,5,7);
	oddList: List[Int] = List(1, 3, 5, 7)

We see that Scala responds that a List has been created, along with brackets around the type of the elements it contains. So, List[Int] is read as “a List of Ints” and so on. This is to say that List is a parameterized data structure: it is a container that holds elements of specific types. 

Few Tips
We can also create Lists with mixtures of types.

scala> val intsAndDoubles  = List (1,1.5,2,2.5)
	intsAndDoubles: List[Double] = List(1.0, 1.5, 2.0, 2.5)

scala> val embeddedList = (fruitList,oddList);
	embeddedList: (List[String], List[Int]) = (List(Mango, Orange, PineApple),List(1, 3, 5, 7))

Use Case for Reducer 
scala> val numbers = List(1,2,3,4,5)
	numbers: List[Int] = List(1, 2, 3, 4, 5)

scala> val total = numbers.reduce((a:Int, b:Int) => a+b)
	total: Int = 15

List methods
scala> fruitList.length
	res48: Int = 3

Comments: The notation variable.method indicates that you are invoking a function that is specific to the type of that variable on the value in that variable. Scala is an object-oriented language, which means that every value has a set of actions that comes with it. Which actions are available depends on its type. 

scala> 2.+(3)
	res49: Int = 5

scala> "Good".+("Evening")
	res51: String = GoodEvening	

Comments: Lets return to Lists and what we can do with them. “Addition” of two lists is their concatenation and is indicated with “++“.

scala> val oddList = List(1,3,5,7);
	oddList: List[Int] = List(1, 3, 5, 7)

scala> val evenList = List (2,4,6,8);
	evenList: List[Int] = List(2, 4, 6, 8)

scala> val completeList = oddList ++ evenList
	completeList: List[Int] = List(1, 3, 5, 7, 2, 4, 6, 8)

Comments: We can append a single item to the front of a List with “::“.

scala> val completeList = 0 :: oddList ++ evenList
	completeList: List[Int] = List(0, 1, 3, 5, 7, 2, 4, 6, 8)

And sort a list with sorted, and reverse it with reverse, and do both in sequence

scala> completeList.sorted
	res52: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8)

scala> completeList.reverse
	res54: List[Int] = List(8, 6, 4, 2, 7, 5, 3, 1, 0)

scala> completeList.sorted.reverse
	res55: List[Int] = List(8, 7, 6, 5, 4, 3, 2, 1, 0)

Note: List is immutable: you cannot change it, so all of these operations will always return new Lists. 

scala> val myList = completeList.sorted
	myList: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8)

scala> myList(2);
	res57: Int = 2

Another useful method is slice, which gives you a sublist from one index up to, but not including, another.
scala> myList.slice(2,6)
	res58: List[Int] = List(2, 3, 4, 5)

Therefore, the slice gave us a list with the elements from index 2 (the third element) up to index 5 (the sixth element).

Few Tips
On lists that contain numbers, we can use the sum method.
scala> myList.sum
	res60: Int = 36

One thing we often want to do with lists is obtain a String representation of their contents in some visually useful way. For example, we might want a fruitList to be a String with one item per line, or a list of Ints to have a comma between each element. The mkString method does just what we need.

scala> fruitList.mkString("\n")
	res61: String =

Want to know if a list contains a particular element? Use contains on the list.
scala> fruitList.contains("Apple")
	res63: Boolean = false

scala> fruitList.contains("Mango")
	res64: Boolean = true

Functions in Scala

Variables are more useful when used in the context of functions in which a variable like x can be injected with different values by the user of a function. Let’s consider converting degrees Fahrenheit to Celsius. To convert 87, 92, and 100 from Fahrenheit to Celcius, we could do the following.

scala> (87 - 32) * 5 / 9.0
	res32: Double = 30.555555555555557

scala> (92 - 32) * 5 / 9.0
	res33: Double = 33.333333333333336

Obviously, there is a lot of repetition here. Functions allow us to specify the common parts of such calculations, while allowing variables to specify the parts that may be different. In the conversion case, the only thing that changes is the temperature reading in Fahrenheit. Here’s how we declare the appropriate function in Scala.

def <identifier>(<identifier>: <type>[, ... ]): <type> = <expression>

scala> def f2c (x : Double) =  (x - 32) * 5 / 9.0
	f2c: (x: Double)Double

Breaking this down, we have:
    (1) def is a Scala keyword indicating that a function is being defined
    (2) f2c (Fahrenheit to Celsius) is the name given to the function
    (3) (x: Double) is the parameter to the function, which is a variable named x of type Double
    (4) (x – 32) * 5/9.0 is the body of the function, which will take the value given by the user of the function	
scala> f2c(87)
	res34: Double = 30.555555555555557

scala> f2c(92)
	res36: Double = 33.333333333333336

A procedure is a function that doesn’t have a return value. Any function that ends with a statement, such as a println() call, is also a procedure. If you have a simple function without an explicit return type that ends with a statement, the Scala compiler will infer the return type of the function to be Unit

scala> def myFunction = {
  println("Good Afternoon");
	myFunction: Unit

scala> myFunction
	Good Afternoon

scala> def log(d: Double): Unit = println(f"Got Value : $d%.2f")
	log: (d: Double)Unit

scala> log(2.547)
	Got Value : 2.55

Functions With Empty Parentheses

scala> def hi = "Hi, Good Evening"
	hi: String

scala> hi
	res0: String = Hi, Good Evening
def <identifier>: <type> = <expression>
scala> def hi : String = "Hi, Very Good Evening"
	hi: String

scala> hi
	res1: String = Hi, Very Good Evening	

def <identifier>()[: <type>] = <expression>

scala> def message() : String = "Good Morning"
	message: ()String

scala> message()
	res0: String = Good Morning

scala> message
	res1: String = Good Morning

Recursive Functions

scala> def power(x : Int, y : Int) : Int = {
   if (y>=1){
     x * power(x, y-1);
scala> power(2,3)
	res2: Int = 8	

Calling Nested Functions

scala> def max(a:Int, b:Int, c:Int) = {
   def max(d:Int, e:Int) = if(d > e) d else e
   max (a, max(b,c))
max: (a: Int, b: Int, c: Int)Int

scala> max (2,5,7)
	res3: Int = 7

Calling Functions With Named Parameters

<function name>(<parameter> = <value>)
scala> def greetings(prefix: String, name: String) = s"$prefix. $name"

scala> val myGreetings = greetings("Ms", "Brown")
myGreetings: String = Ms. Brown

Calling Functions Parameters With Default Values

scala> def greetings(prefix: String = "", name: String) = s"$prefix $name"
	greetings: (prefix: String, name: String)String

scala> val myGreetings = greetings(name="Tom");
	myGreetings: String = " Tom"

Calling Functions Using VarArg Parameters

scala> def sum(items: Int*): Int = {
  var sum = 0;
  for(i <- items) {
    sum = sum + i;

scala> sum(10,20,30)
	res4: Int = 60

Calling Functions Using Parameter Groups

scala> def max(x: Int)(y: Int) = if (x > y) x else y
	max: (x: Int)(y: Int)Int

scala> max(10)(20)
	res5: Int = 20

Calling Higher-Order Functions

scala> def safeStringOperation(value: String, func: String => String) = {
  if (value==null){
safeStringOperation: (value: String, func: String => String)String

scala> def reverser(value : String) = {
reverser: (value: String)String

scala> safeStringOperation(null, reverser)
	res5: String = null

scala> safeStringOperation("Apple",reverser)
	res6: String = elppA

Function Literals

scala> val getDouble = (x: Int) => x*2
	getDouble: Int => Int = <function1>

scala> getDouble(2)
	res0: Int = 4

Use Case-1 (Higher-Order Functions + Function Literals)

scala> def safeStringOperation(value: String, func: String => String) = {
  if (value==null){
safeStringOperation: (value: String, func: String => String)String
scala> safeStringOperation("Apple", (data:String)=>data.reverse)
	res2: String = elppA	

Use Case-2 (Higher-Order Functions + Function Literals)

scala> def safeStringOperation(value: String, func: String => String) = {
  if (value==null){
safeStringOperation: (value: String, func: String => String)String

scala> safeStringOperation("Apple", data=> data.reverse)
res3: String = elppA

Comments: No need to specify the data type. It is inferred from the first parameter

Placeholder Syntax

scala> def safeStringOperation(value: String, func: String => String) = {
  if (value==null){

scala> safeStringOperation("Apple", _.reverse)
res4: String = elppA

Scala Expressions, Variables and Basic Types

We’ll use Scala REPL for entering Scala expressions and seeing what the result of evaluating them is. REPL stands for Read-Eval(uate)-Print-Loop, which means it is a program that
(1) reads the expressions you type in,
(2) evaluates them using the Scala Compiler,
(3) prints out the result of an evaluation, and then
(4) waits for you to enter further expressions.

Scala in Action from Command Prompt

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

	Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
	Type in expressions for evaluation. Or try :help.

Comments: The scala> line is the prompt that the REPL is waiting for you to enter expressions.

Case Study – 1

scala> "Hello World"
	res8: String = Hello World

scala> 2017
	res9: Int = 2017

scala> "2000"
	res10: String = 2000

scala> 3+4
	res11: Int = 7

scala> "2" + "3"
	res13: String = 23

scala> println("Hi,\nGood Morning");
	Good Morning	

Case Study – 2

scala> print ("Hello World")
	Hello World
scala> print (3+4)

Comments: Following is the workflow for above statement:- 
	(1) Scala evaluates 3 + 4, which is 7.
	(2) Scala passes that value to the command prompt.
	(3) print outputs “7"

We often need to store the result of evaluating an expression to a variable for later use
scala> val x = 3+4
	x: Int = 7
scala> print(x)

Here, x is a variable, which we’ve indicate by prefacing it with val, which indicates it is a fixed variable whose value cannot change. We  can choose the names for variables, but they must follow some rules.
    (1) Variable names may contain: letters, numbers, underscore
    (2) They should not start with a number
    (3) They should not be identical to one of the “reserved words” that Scala has already defined, such as for, if, val, var, etc.

Few Working Tips
scala> print(x)
scala> print (x+5)
scala> x+10
	res23: Int = 15
scala> x
	res25: Int = 5
scala> 7/2
	res26: Int = 3
scala> 7.0/2.0
	res27: Double = 3.5

Case Study – 3

scala> val a : Int = 20    // We are doing naming here with help of "val a"
	a: Int = 20

Syntax :- val <identifier> [:<type>] = <expression>

scala> print (a)
scala> a /2
	res29: Int = 10

Comments: The a : Int portion of the line indicates that the variable a has the type Int. Here are some examples of other variables with different types.

scala> val b: Double = 2.25
	b: Double = 2.25

scala> val c: String = "Hello world"
	c: String = Hello world

scala> val pi: Int = 3.14
	<console>:11: error: type mismatch;
	 found   : Double(3.14)
	 required: Int
		   val pi : Int = 3.14
Comments: Importantly, we cannot assign the variable a type that conflicts with the result of the expression. Here, we try to assign a Double value to a variable of type Int, and Scala reports an error.
scala> val pi: Double = 3.14
	pi: Double = 3.14

scala> val atSymbol: Char = '@'
	atSymbol: Char = @

scala> val l: Long = 20
	l: Long = 20

scala> val i: Int = l.toInt
	i: Int = 20		

Case Study – 4

In addition to variables declared with val, Scala allows variables to be declared with var — these variable can have their values reassigned. A few examples are the easiest way to see the difference and syntax is var <identifier>[:<type>] = <expression>

scala> val a = 5
	a: Int = 5

scala> a = 10
<console>:12: error: reassignment to val
       a =10
scala> var b = 5
	b: Int = 5
scala> b = 10
	b: Int = 10

scala> b
	res31: Int = 10

Case Study – 5

scala> val x: Int = 5
	x: Int = 5

scala> x 
	res0: Int = 5

scala> x * 2
	res1: Int = 10

scala> res0 * res1
	res2: Int = 50

Case Study – 6
A multiline String can be created using triple-quotes. Multiline strings are literal, and so do not recognize the use of backslashes as the start of special characters:


scala> val greeting = """She suggested reformatting the file
     | by replacing tabs (\t) with newlines (\n);
     | "Why do that?", he asked. """
greeting: String =
"She suggested reformatting the file
by replacing tabs (\t) with newlines (\n);
"Why do that?", he asked. "	

Case Study – 7 :: String Interpolation

scala> val item = "apple"
	item: String = apple

scala> s"How do you like ${item}s?"
	res0: String = How do you like apples?

scala> s"Fish n chips n vinegar, ${"pepper "*3}salt"
	res1: String = Fish n chips n vinegar, pepper pepper pepper salt

Case Study – 8 :: An Overview Of Scala Types

scala> val isTrue = !true
isTrue: Boolean = false

scala> val isFalse = !true
isFalse: Boolean = false

scala> val unequal = (5 != 6)
unequal: Boolean = true

scala> val isLess = (5 < 6) 
isLess: Boolean = true 

scala> val unequalAndLess = unequal & isLess
unequalAndLess: Boolean = true

scala> val definitelyFalse = false && unequal
definitelyFalse: Boolean = false

An Overview on Garbage Collector Algorithms

Before we move into the details of algorithms that are used in Java Virtual Machine (JVM), let’s have a common understanding of what GC Roots are. These are the objects which are directly accessible from outside the heap memory.
(1) Active Threads
(2) Static Variables
(3) Local Variables (Accessible via Stack of a Thread)
(4) JNI References

There are three basic types of algorithms that are used in Java Virtual Machine (JVM):-
(1) Mark-sweep
(2) Mark-sweep-compact
(3) Mark-copy

Mark:- All of the algorithms discussed have the same mark phase. Marking phase is about traversing the whole object graph, starting from GC Roots. When GC visits the object, it marks it as accessible and thus alive. All the objects which are not reachable from GC Roots are garbage. Marking requires Stop-The-World (STW) pauses, because the running application threads could interfere. How long the STW pause is, depends mostly on the number of visited objects.

Mark-Sweep:-After marking phase, we have the memory space which is occupied by visited (accessible via GC Roots) and unvisited objects. Sweep phase releases the memory fragments which contains unreachable objects. It is simple, but because the dead objects are not necessarily next to each other, we end up having a fragmented memory. That’s not bad but trying to fit a too large object into the memory could potentially lead to OutOfMemoryError.

Mark-Sweep-Compact:-This algorithm fixes the problem with fragmented memory. After all alive objects are marked, they are moved to the beginning of the memory space. That helps to avoid having too fragmented (split) memory, but compacting the heap isn’t for free. Copying objects and updating all references to them take time and it all happens during STW pause.

Mark-Copy:- Mark-copy algorithm copies all alive objects to a new memory region. The previously occupied region is considered to be free. Next time mark-copy is executed, all the alive objects are moved back to the previous memory region. As you can imagine, this, of course, leads to a memory compaction. Unfortunately, it requires additional extra region large enough to fit all live objects at any given point in time.

Outlining Garbage Collectors

Java Virtual Machine (JVM) heap is divided into two different Generations. One is called Young Generation and the second one is Old Generation (sometimes referred to as Tenured). The Young Generation is further separated into two main logical sections: Eden and Survivor spaces. There are also Virtual spaces for both Young and the Old Generations which are used by Garbage Collectors to resize other regions – mainly to meet different GC goals.

Object Life Cycle
Objects start their journey in Eden space of the Young Generation. When Eden fills up, so called Minor GC is performed: all application threads are stopped (Stop-The-World Pause), objects which are not used anymore are discarded and all other objects from the Eden are moved to the first Survivor space (S0). Next time a Minor GC is performed, the objects goes from S0 to the second Survivor space (S1). All live objects from Eden goes to S1 as well. Notice that it leads to differently aged object in the Survivor space – we have objects from Eden and objects which were already in the Survivor space. Next iteration of Minor GC moves the objects from S1 back to the S0, so the Survivor spaces switch every GC. It is significant to understand the switching of objects in Survivor spaces because when object reaches certain age threshold, it is promoted to the Old Generation. It leads to Survivor space fragmentation (division) which can be easily eliminated with moving all objects from S0 to S1 and back every Minor GC. Eventually, when the Old Generation fills up, a Major GC will be performed on the Old Generation which cleans it up and compacts that space. If and how Stop-The-World pauses occur during Major GC depends on specific GC algorithm used.

Types of Garbage Collectors
Let’s have an overview on three types of garbage collectors:-

(1) Serial Collector: As the name suggests, the collection is performed by only one thread. Stop-the-world (STW) pauses are necessary during both Minor and Full GC. This collector uses the Mark-Copy algorithm for the Young Generation, whereas the Old Generation is cleaned up using the Mark-Sweep-Compact algorithm. Serial GC is designed for single-threaded environments (usually client-class machines) and for relatively small heaps.

(2) Parallel Collector: The Young collection is parallelized by multiple threads which makes Minor GC much faster. As a result, this collector leads to shorter, but more frequent Young collection STW pauses. Since JDK 7u4 [Java 7 update release 4], the Old Generation is also collected by multiple threads by default (and also causes stop-the-world pauses). This collector also uses the Mark-Copy algorithm in the Young Generation and Mark-Sweep-Compact in the Old Generation, but both copy and compact phases are executed by multiple threads.

(3) Concurrent Mark and Sweep Collector: Minor GC is performed with multiple threads using the parallel Mark-Copy algorithm. All application threads are stopped then. The Old Generation is mostly collected concurrently – application threads are paused for very short periods of time when the background GC thread scans the Old Generation. The actual algorithm used during Major GC is concurrent Mark-Sweep. Concurrent Mark and Sweep is the collector which doesn’t compact the Tenured space (Old Generation) and thus the memory can be left fragmented. Due to lack of heap compaction, when GC is not able to fit new objects into the memory, JVM fallbacks to the serial mark-sweep-compact algorithm to defragment and compact the Old Generation. That’s when performance degradation comes into play – all application threads are stopped and just one single thread is responsible for cleaning and compacting the Tenured space.

(4) G1GC (Garbage First Garbage Collector): Garbage First (G1) is a new low-pause garbage collector designed to process large heaps with minimal pauses. The heap is broken down into several regions of fixed size (while still maintaining the generational nature of the heap). That kind of design allows us to get rid of long STW pauses when the entire Young or Old Generations are processed. Now, each region can be collected separately which leads to shorter, but more frequent STW pauses. G1 copies objects from one region into another, which means that the heap is at least partially compacted. G1 uses an incremental version of the Mark-Sweep-Compact algorithm.

PermGen and MetaSpace
PermGen is an abbreviation for Permanent Generation and it’s a special heap space which is separate from the main Java heap where JVM keeps track of metadata of the classes which have been loaded. In Java 8, PermGen has been renamed to Metaspace – with some subtle differences. From dvelopment perspective, it is important to note that Metaspace has unlimited default maximum size. On the contrary, PermGen from Java 7 and earlier has the default maximum size of 64 MB on 32-bit JVM and 82 MB on 64-bit one.

ORA-28040: No matching authentication protocol error

We have got following error in Application logs and we were made to cross-check our JVM settings.

ERROR [2016-06-06 03:32:55,521]|[server.startup : 1]|[null]|getConnection
java.sql.SQLException: ORA-28040: No matching authentication protocol
DSRA0010E: SQL State = 99999, Error Code = 28,040
at oracle.jdbc.driver.T4CTTIoer.processError(
at oracle.jdbc.driver.T4CTTIoer.processError(
at oracle.jdbc.driver.T4CTTIoer.processError(
at oracle.jdbc.driver.T4CTTIoauthenticate.processError(
at oracle.jdbc.driver.T4CTTIfun.receive(
at oracle.jdbc.driver.T4CTTIfun.doRPC(
at oracle.jdbc.driver.T4CTTIoauthenticate.doOSESSKEY(
at oracle.jdbc.driver.T4CConnection.logon(
at oracle.jdbc.driver.PhysicalConnection.&amp;lt;init&amp;gt;(
at oracle.jdbc.driver.T4CConnection.&amp;lt;init&amp;gt;(
at oracle.jdbc.driver.T4CDriverExtension.getConnection(
at oracle.jdbc.driver.OracleDriver.connect(
at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(
at oracle.jdbc.pool.OracleDataSource.getConnection(
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPhysicalConnection(

It was determined that removing JVM parameter -Doracle.jdbc.thinLogonCapability=o3 will fix the ORA-28040: No matching authentication protocol error. I remembered that we added this JVM parameter for certain applications during the WebSphere 7 upgrade. The problem was that certain applications running on WebSphere 7 with JDK 1.6 and ojdbc6.jar was not able to login to the Database. This was because of an Oracle driver “issue” when dealing with external 3rd party JCE libraries such as BouncyCastle.

Purpose of [^\x20-\x7E] in Regular Expressions

Purpose of [^\x20-\x7E] in Regular Expressions defines all characters that are not (^) in the range \x20-\x7E (hex 0x20 to 0x7E). According to, those are characters from ‘space’ to ‘~’. Hence, given below Java code will work very efficiently:-

String updateMessage = message.replaceAll("[^\\x20-\\x7e]", "");

Happy Coding !!