Make complaints about big data left and right hands plus technology Tucao group to get more information
preface
As an object-oriented functional programming language, Scala combines object-oriented programming with functional programming to make the code more concise, efficient and easy to understand. That's why Scala is popular.
As a JVM language, most components of the big data ecosystem are developed in Java language, and Scala can be seamlessly mixed with Java, so it can be well integrated into the big data ecosystem.
primary coverage
Some basic things are no longer listed, such as development environment, loops, exceptions, generics, etc. This article only introduces special places, focusing on concept understanding and usage.
- Variables and data types
- Functional programming
- Higher order function
- Anonymous function
- closure
- Function coritization
- object-oriented
- Classes and objects
- Companion Object
- Idiosyncrasy
- pattern matching
- Implicit conversion
Variables and data types
Variable (var declares variable, val declares constant)
var modified variables can be changed
The variable modified by val cannot be changed
But is that true?
For the following definitions
class A(a: Int) { var value = a } class B(b: Int) { val value = new A(b) }
Effect test
val x = new B(1) x = new B(1) // Error, because x is decorated by val, the reference cannot be changed x.value = new A(1) // Error, because x.value is modified by val, the reference cannot be changed x.value.value = 1 // Correct. x.value.value is modified by var and can be re assigned
In fact, the object reference modified by var can be changed, while that modified by val cannot be changed, but the state of the object can be changed.
Variable and immutable understanding
We know that the List in scala is immutable, and the Map is variable and immutable. Look at the following example
var variable and List immutable combination
var list = List("Left","right") list += "hand"
Understanding is
The object that var list points to is List("left", "right")
Later, modify the direction of the list, because it is a variable var modification, and the list can point to a new List("left", "right", "hand")
If it is the following (an error will be reported)
val list = List("Left","right") list += "hand"
val var and Map variable and immutable
var map = Map( "Left" -> 1, "right" ->1, ) map+=("hand"->1)
val map=scala.collection.mutable.Map( "Left" -> 1, "right" ->1, ) map+=("hand"->1)
understand
Immutable map when adding elements, the original map remains unchanged, and a new map is generated to save the original map + added elements.
When adding elements to a variable Map, you do not need to generate a new Map, but directly add the elements to the original Map.
What val is immutable is only the pointer, which has nothing to do with the object map.
data type
data type | describe |
---|---|
Byte | 8-bit signed complement integer. The range of values is - 128 to 127 |
Short | 16 bit signed complement integer. The range of values is - 32768 to 32767 |
Int | 32-bit signed complement integer. The range of values is - 2147483648 to 2147483647 |
Long | 64 bit signed complement integer. The value range is - 9223372036854775808 to 9223372036854775807 |
Float | 32-bit, IEEE 754 standard single precision floating-point number |
Double | 64 bit IEEE 754 standard double precision floating point number |
Char | 16 bit unsigned Unicode character with interval value of U+0000 to U+FFFF |
String | Character sequence |
Boolean | true or false |
Unit | Indicates no value, which is equivalent to void in other languages. The result type used as a method that does not return any results. Unit has only one instance value, written as (). |
Null | null or empty reference |
Nothing | Nothing type is at the bottom of Scala's class hierarchy; It is a subtype of any other type. |
Any | Any is a superclass of all other classes |
AnyRef | AnyRef class is the base class of all reference classes in Scala |
Functional programming
Higher order function
Higher order functions are functions that use other functions as arguments or return a function as a result. In Scala, functions are "first-class citizens".
Simple example
val list=List(1,2,3,4) val function= (x:Int) => x*2 val value=list.map(function)
Method is a function
def main(args: Array[String]): Unit = { val list=List(1,2,3,4) val value=list.map(function) } def function (x:Int)=x*2
Function that returns the function
def calculate(symbol:String): (String,String)=>String ={ symbol match { case "Splicing mode 1" => (a:String,b:String)=> s"Splicing mode 1:$a , $b" case "Splicing mode 2" => (a:String,b:String)=> s"Splicing mode 2: $b , $a" } }
val function: (String, String) => String = calculate("Splicing mode 2") println(function("big data", "Left and right hands"))
Anonymous function
The syntax for defining anonymous functions in Scala is very simple. The left side of the arrow is the parameter list and the right side is the function body.
After using anonymous functions, our code becomes more concise.
var inc = (x:Int) => x+1 var x = inc(7)-1
It can also have no parameters
var user = () => println("Big data left and right")
closure
A closure is a function whose return value depends on one or more variables declared outside the function.
Generally speaking, closures can be simply regarded as another function that can access local variables in a function.
The simple understanding is that the variables inside the function can still be accessed from the outside when they do not act on.
val function= (x:Int) => x*2
The essence of closure is the mixing of code and nonlocal variables
Closure = code + nonlocal variables used
val fact=2 val function= (x:Int) => x*fact
Function coritization
Coriolism refers to the process of changing the original function that accepts two parameters into a new function that accepts one parameter. The new function returns a function with the original second parameter as the parameter.
First define a simple
def add(x:Int,y:Int)=x+y use add(1,2)
Function deformation (this method is called coritization)
def add(x:Int)(y:Int) = x + y use add(1)(2)
Implementation process
add(1)(2) actually calls two ordinary functions (non Coriolis functions) in turn
The first call uses a parameter x and returns the value of a function type.
The value of this function type is called a second time with parameter y.
Receive one x Is a parameter that returns an anonymous function Receive one Int Type parameter y,The function body is x+y. def add(x:Int)=(y:Int)=>x+y (1) val result = add(1) // result= (y:Int)=>1+y (2) val sum = result(2) (3) sum=3
object-oriented
Classes and objects
A class is an abstraction of an object, and an object is a concrete instance of a class. Classes are abstract and do not occupy memory, while objects are concrete and occupy storage space. Class is a blueprint for creating objects. It is a software template that defines methods and variables included in specific types of objects.
Class can have class parameters
Class parameters can be used directly in the body of the class. Class parameters can also be prefixed with var and decorated with private, protected and override. The scala compiler collects class parameters and creates the main constructor of the class with the same parameters., And compile any code inside the class that is neither a field nor a method definition into the main constructor.
class Test(val a: Int, val b: Int) { // }
Sample class
case class is generally translated into sample class. It is a special class that can be optimized for pattern matching.
When a class is called case class. It has the following functions:
- If the parameter in the constructor is not declared as var, it defaults to val.
- Automatically create the associated object, and implement the sub apply method in it, so that we can create the object without using new directly.
- The companion object will also help us implement the unapply method, so that we can apply case class to pattern matching.
- Implement your own toString, hashCode, copy and equals methods
case class person( name:String, age:Int )
Objects and companion objects
Scala singleton object is very important. It does not have static classes, static members and static methods as in Java, but Scala provides an object object, which is similar to Java's static class. Its members and methods are static by default.
Defining a singleton object does not mean defining a class, so you can't use it to create a new object. When a singleton object shares the same name with a class, it is called the companion object of the class.
Class and its associated objects must be defined in the same source file. Class is called the companion class of this singleton object.
Class and its companion objects can access each other's private members.
object Test { private var name="big data" def main(args: Array[String]): Unit = { val test = new Test() println(test.update_name()) } } class Test{ def update_name(): String ={ Test.name="Left and right hands" Test.name } }
Trait
scala trait is equivalent to the java interface. In fact, it is more powerful than the interface.
Unlike interfaces, it can also define the implementation of properties and methods.
In general, scala classes can only inherit a single parent class, but if it is a trait, it can inherit multiple. From the result, it implements multiple inheritance (keyword with). In fact, scala trait is more like an abstract class of java.
object Test extends UserImp with AddressImp { override def getUserName(): String = ??? override def getAddress(): String = ??? } trait UserImp{ def getUserName():String } trait AddressImp{ def getAddress():String }
pattern matching
Take java switch as an example. java switch only does some basic type matching, and then performs some actions, and there is no return value.
scala's pattern matching match is much more powerful. In addition to matching values, it can also match types.
def calculate(symbol:String): (String,String)=>String ={ symbol match { case "Splicing mode 1" => (a:String,b:String)=> s"Splicing mode 1:$a , $b" case "Splicing mode 2" => (a:String,b:String)=> s"Splicing mode 2: $b , $a" } }
To my surprise (just a few lines)
Quick row def quickSort(list: List[Int]): List[Int] = list match { case Nil => Nil case List() => List() case head :: tail => val (left, right) = tail.partition(_ < head) quickSort(left) ::: head :: quickSort(right) } Merge def merge(left: List[Int], right: List[Int]): List[Int] = (left, right) match { case (Nil, _) => right case (_, Nil) => left case (x :: xTail, y :: yTail) => if (x <= y) x :: merge(xTail, right) else y :: merge(left, yTail) }
Implicit conversion
Scala provides implicit conversion and implicit parameter functions, which are very characteristic functions. It is a function that programming languages such as Java do not have. It allows you to manually specify and convert objects of one type to objects of other types. Through these functions, very powerful and special functions can be realized.
rule
(1) Before using implicit conversion, you need to use import to reference the implicit conversion to the current scope or define the implicit conversion in the scope.
(2) Implicit conversions can only be operated if no other conversions are available. If more than one implicit conversion function is defined for the same source type in the same scope, if multiple implicit conversion functions can match, the compiler will report an error. Therefore, please remove unnecessary implicit definitions when using.
Implicit conversion of data types
String type cannot be automatically converted to Int type, so when a variable or constant of Int type is given a value of string type, the compiler will report an error. But
implicit def strToInt(str: String) = str.toInt def main(args: Array[String]): Unit = { val a:Int="100" print(a) }
Implicit conversion of parameters
The so-called implicit parameter refers to defining an implicit modified parameter in a function or method. At this time, Scala will try to find a specified type of implicit modified object, that is, implicit value, and inject parameters.
object Test { private var name="big data" implicit val test = new Test def getName(implicit test:Test): Unit ={ println(test.update_name()) } def main(args: Array[String]): Unit = { getName } } class Test{ def update_name(): String ={ Test.name="Left and right hands" Test.name } }