Scala grammar tutorial

Chapter 1 Introduction to Scala

1.1 general

Scala is a static type programming language that takes Java virtual machine (JVM) as the running environment and combines the best features of object-oriented and functional programming (static languages need to be compiled in advance, such as Java, c, c + +, dynamic languages such as js).

1) Scala is a multi paradigm programming language. Scala supports object-oriented and functional programming. (multi paradigm is a variety of programming methods

The meaning of law. There are four programming methods: process oriented, object-oriented, generic and functional.)

2) scala source code (. scala) will be compiled into Java bytecode (. Class), and then run on the JVM. You can call the existing Java class library to realize the seamless connection between the two languages.

3) As a single language, Scala is very concise and efficient.

4) In the design of Scala, Martin odesky refers to the design idea of Java. It can be said that Scala originates from Java. At the same time, Martin odesky also adds his own idea to integrate the characteristics of functional programming language into Java. Therefore, for students who have studied Java, they should only find out the similarities and differences between Scala and Java in the process of learning Scala, You can quickly master the language Scala.

1.2 environment construction

Based on jdk1 eight

Download scala2 twelve point one one

Configuring scala environment variables

1.3 coding

package chapter01

class Student(name:String,info: Int) {
  def printInfo():Unit ={
    println(name+" "+info+" "+Student.school)
  }
}

object Student{
  val school:String = "Hebei Agricultural University"
//Companion Object 
  def main(args: Array[String]): Unit = {
    val student = new Student("Zhang San",20)
    student.printInfo()
  }
}

Student$.class

package chapter01;

public final class Student$
{
  public static  MODULE$;
  private final String school;

  static
  {
    new ();
  }

  public String school()
  {
    return this.school;
  }
  public void main(String[] args) {
    Student student = new Student("Zhang San", 20);
    student.printInfo();
  }
  private Student$() {
    MODULE$ = this;

    this.school = "Hebei Agricultural University";
  }
}

Student.java

package chapter01;

import scala.Predef.;
import scala.reflect.ScalaSignature;

@ScalaSignature(bytes="\006\001}2Aa\003\007\001\037!Aa\003\001B\001B\003%q\003\003\005#\001\t\005\t\025!\003$\021\0251\003\001\"\001(\021\025a\003\001\"\001.\017\025\tD\002#\0013\r\025YA\002#\0014\021\0251c\001\"\0015\021\035)dA1A\005\002YBaa\016\004!\002\0239\002\"\002\035\007\t\003I$aB*uk\022,g\016\036\006\002\033\005I1\r[1qi\026\024\b'M\002\001'\t\001\001\003\005\002\022)5\t!CC\001\024\003\025\0318-\0317b\023\t)\"C\001\004B]f\024VMZ\001\005]\006lW\r\005\002\031?9\021\021$\b\t\0035Ii\021a\007\006\00399\ta\001\020:p_Rt\024B\001\020\023\003\031\001&/\0323fM&\021\001%\t\002\007'R\024\030N\\4\013\005y\021\022\001B5oM>\004\"!\005\023\n\005\025\022\"aA%oi\0061A(\0338jiz\"2\001\013\026,!\tI\003!D\001\r\021\02512\0011\001\030\021\025\0213\0011\001$\003%\001(/\0338u\023:4w\016F\001/!\t\tr&\003\0021%\t!QK\\5u\003\035\031F/\0363f]R\004\"!\013\004\024\005\031\001B#\001\032\002\rM\034\007n\\8m+\0059\022aB:dQ>|G\016I\001\005[\006Lg\016\006\002/u!)1H\003a\001y\005!\021M]4t!\r\tRhF\005\003}I\021Q!\021:sCf\004")
public class Student
{
  private final String name;
  private final int info;

  public static void main(String[] paramArrayOfString)
  {
    Student..MODULE$.main(paramArrayOfString);
  }

  public static String school()
  {
    return Student..MODULE$.school();
  }

  public void printInfo()
  {
    Predef..MODULE$.println(2 + this.name + " " + this.info + " " + Student..MODULE$.school());
  }

  public Student(String name, int info)
  {
  }
}

Chapter II variables and data types

2.1 variables and constants

var variable name: variable type = value

val constant name: constant type = value

Variable types can be omitted, and the compiler will automatically infer

Variables are not needed where constants can be used

(1) When declaring variables, types can be omitted

(2) It cannot be modified after the type is determined

(3) When a variable is declared, it must have an initial value

(4) When declaring variables, you can use var and Val, var can be changed and val cannot be changed

2.2 specification of identifiers

Starts with an operator and contains only operators (+ - * / #! Etc.)

Use back quotation marks Any string included, even Scala keywords (39) can be used

• package, import, class, object, trait, extends, with, type, for • private, protected, abstract, sealed, final, implicit, lazy, override

• try, catch, finally, throw

• if, else, match, case, do, while, for, return, yield

• def, val, var

• this, super • new • true, false, null

2.3 string

(1) String, connected by + sign, can be multiplied by string

(2) printf usage: string, passing value through%.

(3) String template (interpolation string): get variable value through $

var age="hello"
println(s"${age}")

var num = 2.3456
println(f"The num is ${num}%.2f")//Keep two decimal places
println(raw"The num is ${num}%.2f")//raw output original format

//The three quotation mark format can wrap multiple lines of text and keep the original format
s"""""".stripMargin 

2.4 keyboard input

StdIn is the new Scanner

Basic grammar

StdIn.readLine(),StdIn.readShort(),StdIn.readDouble()

2.5 document operation

 def main(args: Array[String]): Unit = {
    //read file
    Source.fromFile("src/main/resources/test.txt").foreach(print)
    //Write data to a file. scala does not have a well encapsulated class library for writing to a file. Just use Java io
    val writer = new PrintWriter(new File("src/main/resources/test1.txt"))
    writer.write("hello scala from java writer")
    writer.close()
  }

2.6 data type

1) All data in Scala are objects and subclasses of Any.

2) In Scala, data types are divided into two categories: numeric type (AnyVal) and reference type (AnyRef). Both value type and reference type are objects.

3) Scala data types still comply with the principle of automatic conversion (implicit conversion) from low-precision value types to high-precision value types

4) StringOps in Scala is an enhancement of String in Java

5) Unit: corresponds to void in Java. It is used for the position of the return value of the method, indicating that the method has no return value. Unit is a data type, and only one object is (). Void is not a data type, but a keyword

6) Null is a type, and only one object is null. It is a subclass of all reference types (AnyRef).

Nothing is a subclass of all data types. It is mainly used when a function has no explicit return value, because in this way, we can return the thrown return value to any variable or function

Chapter III process control

3.1 if else

Syntax is no different from java

But each branch can return a value

The type returned is the last line of branch code block

val age = StdIn.readInt()

    var result = if (age>18){
      println("18")
      15
    } else{
      "000"
    }
    println(result)

3.2 for

to unitl

The difference is that until has no right boundary

for(i <- 1 to 3){
 print(i + " ")
}
println()
------------------------------------------------------
for(i <- 1.to(3){
 print(i + " ")
}

The bottom layer is the method called

for (i <- Range(1,10)){}
//Range without boundary is the companion object


for (i <- 1 until 10){}
//The bottom is the top

foreach loop in scala

for (i <- Array(10,20,30))
for (i <- List(10,20,30))
for (i <- Set(10,20,30))

Cycle guard

There is no continue in scala

for (i <- 0 to 10 if i!=5){}

Cycle step

for(i <- 1 to 3 by 2){}
//Step cannot be 0

reverse

for(i <- 1 to 3 reverse){}
for(i <- 3 to 1 by -1){}

loop nesting

for(i <- 1 to 3; j <- 1 to 3) {
 println(" i =" + i + " j = " + j)
}
//equivalence

for (i <- 1 to 3) {
 for (j <- 1 to 3) {
 println("i =" + i + " j=" + j)
 }
}

Loop return value

Rarely used

object TestFor {
 def main(args: Array[String]): Unit = {
 var res = for(i <-1 to 10) yield {
 i * 2
 }
 println(res)
 }
}
Output result:
Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)

3.3 while do

Because there is no return value in while, when the statement is used to calculate and return the result, it is inevitable to use variables. If the variables need to be declared outside the while loop, it is equivalent to the internal of the loop, which has an impact on the external variables. Therefore, it is not recommended to use, but to use the for loop.

Same as java syntax

3.4 cycle interruption

Scala's built-in control structure specifically removes break and continue in order to better adapt to functional programming. It is recommended to use functional style to solve the functions of break and continue, rather than a keyword. Scala uses breakable control structure to realize break and continue functions.

import scala.util.control.Breaks
import scala.util.control.Breaks._
def main(args: Array[String]): Unit = {
 Breaks.breakable(
 for (elem <- 1 to 10) {
 println(elem)
 if (elem == 5) Breaks.break()//break()
 }
 )
 println("Normal end of cycle")
}

Chapter 4 functional programming

4.1 differences between functions and methods

1) Core concept

(1) A collection of program statements that complete a function is called a function.

(2) Functions in a class are called methods.

2) Case practice

(1) The Scala language can declare any syntax in any syntax structure

(2) Function has no concept of overloading and rewriting; Methods can be overloaded and overridden

(3) Functions in Scala can be defined nested

4.2 function parameters

(1) Variable parameters

(2) If there are multiple parameters in the parameter list, the variable parameters are generally placed last

(3) Parameter default value: generally, the parameter with default value is placed behind the parameter list

(4) Named parameter

Mutable is similar to python

def hello (*str):
    print(type(str))
hello("sac","1")
------------------------
<class 'tuple'>
def hello(string: String*)={
      println(string)
    }

println(hello("1","2"))
----------------------------
WrappedArray(1, 2)

Default value

def hello(string: String = "hello")={
      println(string)
    }

Named parameter

def hello(name,age)={
      println(name+age)
}
hello(age=15,name="Zhang San")

4.3 principle of simplifying functions (key points)

Function saving principle

(1) Return can be omitted. Scala will use the last line of the function body as the return value

(2) If the function body has only one line of code, you can omit curly braces

(3) If the return value type can be inferred, it can be omitted (: omitted together with the return value type)

(4) If there is a return, the return value type cannot be omitted and must be specified

(5) If the function explicitly declares unit, even if the return keyword is used in the function body, it will not work

(6) Scala can omit the equal sign if it expects a type with no return value

(7) If the function has no parameters but declares a parameter list, parentheses can be added or not when calling

(8) If the function does not have a parameter list, the parentheses can be omitted and must be omitted when calling

(9) If you don't care about the name and only care about logical processing, the function name (def) can be omitted

Anonymous function lambda expression

4.4 anonymous functions

A function without a name is an anonymous function.

(X: int) = > {function body}

def fun1(name:String): Unit ={
      println(name)
    }
    val tmp = (name:String)=>{println(name)}
    def fun2(fun:String => Unit): Unit ={
        fun("Zhang San")
    }
    fun2(tmp)

(1) The type of parameter can be omitted and will be automatically deduced according to the formal parameter

fun2((name)=>{println(name)})

(2) If only one parameter is found after the type is omitted, the parentheses can be omitted; Other situations: if there are no parameters and the parameters exceed 1, the parentheses can never be omitted.

fun2( name =>{println(name)})

(3) If an anonymous function has only one line, braces can also be omitted

fun2( name => println(name))

(4) If the parameter appears only once, the parameter is omitted and the following parameters can be used_ replace

x fun2( name => println(_))
fun2( println(_))

Outrageous Edition

fun2(println)

4.5 advanced functions

Function object

def fun1(name:String): Unit ={
    println(name)
}
val tmp = (name:String)=>{println(name)}
def fun2(fun:String => Unit): Unit ={
    fun("Zhang San")
}
val f1 = fun2 _
val f2: String => Unit= fun1

val f1 = fun2 _

You can also return a function object

Function assignment

def func1(s:String): Char=>(Int=>Boolean)={
    def func2(c:Char): Int=>Boolean ={
      def fun3(i:Int):Boolean ={
        if(i==0&&c=='0'&&s=='0') true else false
      }
    fun3
    }
  func2
  }

Function coritization

def func1(i:Int)(s:String)(c:Char):Boolean={
    true
}

4.6 closure

Closure: standard configuration of functional programming

Closure: if a function accesses the value of its external (local) variable, the function and its environment are called closures

def func1(s:String): Char=>(Int=>Boolean)={
    def func2(c:Char): Int=>Boolean ={
      def fun3(i:Int):Boolean ={
        if(i==0&&c=='0'&&s=='0') true else false
      }
    fun3
    }
  func2
  }

When func1 is called, the local variables of the pop-up stack will also be released, but fun3 can still access the local variables of the upper function

This is because scala packages the function objects created by local variables and puts them in heap memory,

4.7 recursion

def con(n:Int): Int = {
      if (n ==0) return 1
        con(n-1) * n
    }
//Tail recursion saves stack space, and the pointer does not need to change
def con1(n:Int):Int = {
    @tailrec //This annotation checks whether the tail recursion is correct
    def loo(n:Int,sum:Int):Int = {
      if(n==0) return sum
        loo(n-1,sum * n)
    }
    loo(n,1)
}

4.8 control abstraction

1) Value call: pass the calculated value

 object TestControl {
 	def main(args: Array[String]): Unit = {
 	def f = ()=>{
 		println("f...")
		10
 }
 	foo(f())
 }
 def foo(a: Int):Unit = {
 	println(a)
 	println(a)
 }
}

2) Call Name: pass the code

object TestControl {
 def main(args: Array[String]): Unit = {
 def f = ()=>{
 println("f...")
 10
 }
 foo(f())
 }
//def foo(a: Int):Unit = {
 def foo(a: =>Int):Unit = {//Notice that there are no parentheses for variable a
 println(a)
 println(a)
 }
}
Output result:
f...
10
f...
10 

Define your own while loop

def myWhile(flag: => Boolean): (=> Unit)=>Unit= {
        def dowhile(con: => Unit):Unit = {
          con
          if (flag)
            dowhile(con)
        }
      dowhile
    }
    var n=10
    myWhile(n>=1){
      println(n)
      n-=1
    }
  }

4.9 lazy loading

When the return value of the function is declared as lazy, the execution of the function will be delayed until we take this value for the first time. This kind of function is called inert function.

Chapter V object oriented

5.1 package description (package statement)

Scala has two package management styles. One is the same as the package management style of Java. Each source file has a package (the package name and the path of the source file are not required to be consistent), and the package name uses "." Separate to represent the hierarchical relationship of packages, such as com atguigu. scala. The other style represents the hierarchical relationship through nested styles, as follows

package com{
package atguigu{
package scala{
}
}
}

The second style has the following characteristics:

(1) Multiple package s can be declared in one source file

(2) The classes in the child package can directly access the contents in the parent package without importing the package

5.2 package object

In Scala, you can define a package object with the same name for each package. The members defined in the package object can be accessed directly as the shared variables of all class es and objects under its corresponding package.

package object com{
val shareValue="share"
def shareMethod()={}
}

If the package is managed in a nested way, the package object can be defined in the same file as the package, but the package object and package declaration should be guaranteed to be in the same scope.

5.3 guide package description

1) Like Java, import can be used at the top, and all classes in this file can be used.
2) Partial import: when to use and when to import. It can be used within its scope of action
3) Wildcard import: import Java util._
4) Name the class: import Java util. {ArrayList=>JL}
5) Import multiple classes of the same package: import Java util. {HashSet, ArrayList}
6) Shielding class: import Java util. {ArrayList =>,}
7) Absolute path of imported package: new root java. util. HashMap

The three default imports in Scala are
import java.lang._
import scala._
import scala.Predef._

5.4 classes and objects

Define class

[modifier] class{

}Public is assumed by default without modifier, and an error will be reported if public is added

A scala file can define multiple classes

class student{
    //This annotation generates set get by default
    @BeanProperty
    private var:String name = "1"
    //The default is public, but the bottom layer is private
    //If you want the attribute to be empty, name =_ Equivalent to null or 0
}

5.5 packaging

The public attribute in scala is actually private at the bottom, and it is operated through the get method (obj.field()) and the set method (obj. Field = (value)). Therefore, Scala does not recommend setting the property to private and then setting the public get and set methods for it. However, since many Java frameworks use reflection to call getXXX and setXXX methods, sometimes in order to be compatible with these frameworks, getXXX and setXXX methods will also be set for Scala properties (implemented through @ BeanProperty annotation).

In Java, access permissions are divided into public, private, protected and default. In Scala, you can achieve the same effect with similar modifiers. But there are differences in use.

(1) The default access permission of properties and methods in Scala is public, but there is no public keyword in Scala.

(2) Private is a private permission, which is only available in the interior of a class and its associated objects.

(3) Protected refers to the protected permission. The protected permission in Scala is more strict than that in Java. The same kind and subclass can be accessed, but the same package cannot be accessed.

(4) private [package name] adds package access permission. Other classes under the package name can also be used

5.6 constructor

Like Java, Scala construction objects also need to call construction methods, and there can be any number of construction methods.

The constructors of Scala class include: main constructor and auxiliary constructor

class Class name(parameter list ) { // primary constructor 
 // Class body
 def this(parameter list ) { // Auxiliary constructor
 }
 def this(parameter list ) { //Auxiliary constructors can have multiple
 }
}

explain:

(1) Auxiliary constructor, the name of the function this, can be multiple. The compiler can distinguish it by the number and type of parameters.

(2) Auxiliary construction methods cannot directly build objects. They must call the main construction method directly or indirectly.

(3) The constructor calls other constructors, which requires that the called constructor must be declared in advance.

5.7 abstract classes

(1) Define abstract class: abstract class Person {} / / mark the abstract class with the abstract keyword

(2) Define abstract attribute: val|var name:String / / an attribute is an abstract attribute without initialization

(3) Define abstract methods: def hello():String / / methods that are declared but not implemented are abstract methods

Rewrite & inherit

(1) If the parent class is an abstract class, the subclass needs to implement the abstract properties and methods, otherwise the subclass also needs to be declared as an abstract class

(2) Overriding non abstract methods requires overriding. Overriding abstract methods can be done without overriding.

(3) the method of calling the parent class in the subclass uses the super keyword.

(4) The subclass implements the abstract attribute, and the abstract attribute of the parent class can be modified with var;

The subclass overrides the non Abstract attribute. The non Abstract attribute of the parent class only supports val type, not var.

Because var is modified as a variable, it can be used directly after subclass inheritance, and there is no need to rewrite it

5.8 single case object (companion object)

1) Basic syntax object person {Val country: String = "China"}

2) Explain

(1) The singleton object is declared with the object keyword

(2) The class corresponding to a singleton object is called an associated class, and the name of the associated object should be consistent with the name of the associated class.

(3) The properties and methods in the singleton object can be accessed directly through the associated object name (class name).

apply method

Through the apply method of the associated object, the object is created without using the new method.

If you want to make the main constructor private, you can add private before ().

When you use the new keyword to build an object, you actually call the construction method of the class. When you directly use the class name to build an object, you call the apply method of the real-time associated object.

5.9 Trait

It is implemented by the interface in java

Basic grammar

trait Trait name {
 subject
}

Traits in Scala can have either abstract attributes and methods or concrete attributes and methods

When the trait conflicts with the class attribute, the attribute needs to be rewritten, otherwise an error will be reported

scala is bound dynamically

No parent class: class name extends trait 1 with trait 2 with trait 3

Parent class: class name extends parent class with trait 1 with trait 2 with trait 3

Multiple trait method conflicts

trait Ball {
 def describe(): String = {
 "ball"
 }
}
trait Color extends Ball {
 override def describe(): String = {
 "blue-" + super.describe()
 }
}
trait Category extends Ball {
 override def describe(): String = {
 "foot-" + super.describe()
 }
}
class MyBall extends Category with Color {
 override def describe(): String = {
 "my ball is a " + super.describe()
 }
}
object TestTrait {
 def main(args: Array[String]): Unit = {
 println(new MyBall().describe())
 }
}
//Output results
//my ball isa blue-foot-ball

5.9 type check and conversion

(1)obj.isInstanceOf[T]: judge whether obj is of type T.

(2)obj.asInstanceOf[T]: strong conversion of obj to T type.

(3) classOf gets the class name of the object.

class Person{
}
object Person {
 def main(args: Array[String]): Unit = {
 val person = new Person
 //(1) Determine whether the object is an instance of a type
 val bool: Boolean = person.isInstanceOf[Person]
 if ( bool ) {
 //(2) Converts an object to an instance of a type
 val p1: Person = person.asInstanceOf[Person]
 println(p1)
 }
 //(3) Get class information
 val pClass: Class[Person] = classOf[Person]
 println(pClass)
 }
}

5.10 enumeration class and application class

Enumeration class: it needs to inherit enumeration

Application class: need to inherit App

// Enumeration class
object Color extends Enumeration {
 val RED = Value(1, "red")
 val YELLOW = Value(2, "yellow")
 val BLUE = Value(3, "blue")
}
// Application class
object Test20 extends App {
 println("xxxxxxxxxxx");
}

Use the type keyword to define a new data type name, which is essentially an alias of the type

type myString = String

Chapter VI collection

6.1 variable and immutable

Scala's collections fall into three categories: sequence Seq, Set and Map. All collections are extended from Iterable.

For almost all collection classes, Scala provides both variable and immutable versions, which are located in the following two packages

Immutable set: Scala collection. immutable

Variable set: Scala collection. mutable

Scala immutable set means that the set object cannot be modified. Each modification will return a new object without modifying the original object. Similar to String objects in java

A variable set is a set that can directly modify the original object without returning a new object. Similar to the StringBuilder object in java

Array and String are special, and implicit conversion is used

Set and Map are collections in Java, but Seq is not in Java. We found that List belongs to Seq, but it is different from List

The for loop has a 1 to 3, which is the Range under IndexedSeq, and the String also belongs to IndexedSeq

Classical data structures such as Queue and Stack are assigned to linear SEQ (linear sequence)

The Map system in scala has a SortedMap, which shows that Scala's Map can support sorting

The difference between IndexedSeq and LinearSeq:

IndexedSeq searches and locates by index, so it is fast. For example, String is an index set

LinearSeq is linear, that is, it has the concept of head and tail. This data structure is generally searched through history

6.2 traversal

definition

definition: val arr1 = new Array[Int](10)

println(arr01.length) // 4
 //(2) Array assignment
 //(2.1) modify the value of an element
 arr01(3) = 10
 //(2.2) assign value to the array in the form of method
 arr01.update(0,1)
 //(3) Traversal array
 //(3.1) view array
 println(arr01.mkString(","))
 //(3.2) general traversal
 for (i <- arr01) {
 println(i)
 }
 //(3.3) simplified traversal
 def printx(elem:Int): Unit = {
 println(elem)
 }
 arr01.foreach(printx)
 // arr01.foreach((x)=>{println(x)})
 // arr01.foreach(println(_))
 arr01.foreach(println)
 //(4) Adding elements (because you create an immutable array, adding elements actually generates new numbers
 Group)
 println(arr01)
 val ints: Array[Int] = arr01 :+ 5
 println(ints)
 }

The second way is to define an array

val arr1 = Array(1, 2)

(1) When defining an array, initial values are assigned directly

(2) Use the apply method to create an array object

6.3 array

val arr01 = ArrayBuffer[Any](3, 2, 5)
arr01.+=(4)
//(3.2) add data to the last array
arr01.append(5,6)
//Inserts data into the specified location (0)
arr01.insert(0,7,8)
arr01.preappend(5,6)
//Deletes the specified subscript element
arr.remove(0)
//Delete multiple from subscript
arr.remove(1,3)
arr1.toBuffer //Immutable array to variable array
arr2.toArray //Variable array to immutable array
//Remove 1 element from array
arr -= 1 
//Specify delimiter traversal
arr.mkString(", ")
//Returns the range of length
a.indices

ArrayBuffer is an ordered collection. The append method () is used to add elements, and variable parameters are supported

Multidimensional array

val arr = Array.ofDim[Double](3,4)
//Description: there are three one-dimensional arrays in the two-dimensional array, and each one-dimensional array has four elements

6.4 list

There is a sequence that cannot be created with a constructor. The bottom layer inherits an abstract class

Only use apply

The value cannot be changed and can be added

//apply method creation
var list = List(0,1)
var list1 = Nil.::(1)
var list2 = 1 :: 2 :: 3 :: Nil
//The two classes implement List Nil. The empty list class:: Class:: method adds the element to the end and returns a new list
//List append list:: returns a nested list that is not the desired append element
// : this method will synthesize a complete list or++ 
// ++A new + + = will be returned and the first one will be overwritten

Variable list

ListBuffer

new and apply

new ListBuffer[Int]()
//Length cannot be defined in advance
ListBuffer(1,2)
3 +=: 4 list += 25 += 25

6.4 assembly

Variable set and immutable set have the same name, but the package name is different

set is a trait. It uses the apply method of the associated object and is out of order

The method is consistent with the list

val list1: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
val list2: List[Int] = List(4, 5, 6, 7, 8, 9, 10)
//(1) Gets the header of the collection
println(list1.head)
//(2) Get the tail of the collection (either the head or the tail)
println(list1.tail)
//(3) Set last data
println(list1.last)
//(4) Set initial data (excluding the last one)
println(list1.init)
//(5) Reverse
println(list1.reverse)
//(6) Take the first (last) n elements
println(list1.take(3))
println(list1.takeRight(3))
//(7) Remove the first (last) n elements
println(list1.drop(3))
println(list1.dropRight(3))
//(8) Union
println(list1.union(list2))
//(9) Intersection
println(list1.intersect(list2))
//(10) Difference set
println(list1.diff(list2))
//(11) Zipper note: if the number of elements in two sets is not equal, the same amount of data will be zipped. If the nested Tuple2 type is not used, the redundant data will be omitted
println(list1.zip(list2))
//(12) Sliding window
list1.sliding(2, 5).foreach(println)

6.5 Map

Map("a" -> 1)
var a :Map [String , String]  = Map()
map.get("a")
//Will not return value, will return Some(1) want to return value get(). get
//When there is no key value, get will report an exception. Use getOrElse("c",0) 
//If null, assign 0
//You can also use map("a") to report exceptions

map.put("a","b")
//Key pair deletion a
map -= "a"
println(map)
map += "sczc" -> "s"
map.update("scac","nu")
map += (("1","1"))
println(map)
//Merge map
map ++= mutable.Map ("2"-> "2")
println(map)

6.6 tuples

//The tuple has a maximum of 22 elements. The creation method is the same as py (). The subscript is immutable from the beginning
//Not a list of Any type. Each tuple length has a separate class Tuple1-22
var tuple = ("1",1,2.1,true)
println(tuple)
//(1,1,2.1,true)
//Access data tuple_ number or tuple. produceElement(num)
println(tuple._1)
//Iterator traversal
for (elem <- tuple.productIterator)
println(elem)
//Nested tuple
var tuple2 = (1,2,(3,3))
println(tuple2._3._1)

Set common functions

//(1) Sum
println(list.sum)
//(2) Product
println(list.product)
//(3) Maximum
println(list.max)
//(4) Minimum value
println(list.min)
//(5) Sort
// (5.1) sort by element size
println(list.sortBy(x => x))
// (5.2) sort by absolute value of elements
println(list.sortBy(x => x.abs))
// (5.3) sort by element size in ascending order
println(list.sortWith((x, y) => x < y))
// (5.4) sort by element size in descending order
println(list.sortWith((x, y) => x > y))

(1) sorted sorts a collection naturally by passing implicit Ordering

(2) sortBy sorts one or more attributes by their type.

(3) sortWith is based on the sorting of functions, and realizes the logic of user-defined sorting through a comparator function. lamda expression

Set computing advanced functions

val list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
 val nestedList: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
 val wordList: List[String] = List("hello world","hello atguigu", "hello scala")
 //(1) Filter
 println(list.filter(x => x % 2 == 0))
 //(2) Conversion / mapping
 println(list.map(x => x + 1))
 //(3) Flattening
 println(nestedList.flatten)
 //(4) Flattening + mapping note: flatMap is equivalent to map operation first and then flatten
 operation
 println(wordList.flatMap(x => x.split(" ")))
 //(5) Grouping
 println(list.groupBy(x => x % 2))
 }

Reduce method

Aggregate the data in the collection through the specified logic, so as to reduce the data and finally obtain the result.

val list = List(1,2,3,4)
 // Combine the data to realize the operation rules
 val i: Int = list.reduce( (x,y) => x-y )
 println("i = " + i)
 // From the perspective of source code, the bottom layer of reduce actually calls reduceLeft
 //val i1 = list.reduceLeft((x,y) => x-y)

Fold folding: a special case of simplification.

val list = List(1,2,3,4)
 // The fold method uses function coritization, and there are two parameter lists
 // The first parameter list is: zero value (initial value)
 // The second parameter list is: simplification rules
 // The bottom layer of fold is actually foldLeft
 val i = list.foldLeft(1)((x,y)=>x-y)
 val i1 = list.foldRight(10)((x,y)=>x-y

Multithreading

(1 to 100).par.map()  //Multiple x's

Chapter 7 pattern matching

Pattern matching in Scala is similar to the switch syntax in Java

var result = operator match {
 case '+' => a + b
 case '-' => a - b
 case '*' => a * b
 case '/' => a / b
 case _ => "illegal"
}

In each case, there is no need to use the break statement to automatically interrupt the case.

Matching type

def describe(x: Any) = x match {
 case i: Int => "Int"
 case s: String => "String hello"
 case m: List[_] => "List"
 case c: Array[Int] => "Array[Int]"
 case someThing => "something else " + someThing
 }

Matching array

scala pattern matching can accurately match collections, such as an array with only two elements and the first element is 0.

val result = arr match {
 case Array(0) => "0" //Match Array(0)
 case Array(x, y) => x + "," + y //Matches the number of two elements
 Group, and then assign the element value to the corresponding x,y
 case Array(0, _*) => "Array starting with 0" //Match starts with 0 and
 array
 case _ => "something else"
 }

Match list

def main(args: Array[String]): Unit = {
 val list: List[Int] = List(1, 2, 5, 6, 7)
 list match {
 case first :: second :: rest => println(first + "-" + 
second + "-" + rest)
 case _ => println("something else")
 }
 }

Match on variable declaration

var first :: second :: three = List(121,2 ,3.5,6)
println(s"$first  $second")


//for loop simplification
for((var1,var2) <- List((1,2),(3,5)))
	println(var1+"   "+var2)
//You can replace the value var2 regardless of the position with_ Only the first value is traversed
for((var1,_) <- List((1,2),(3,5)))
	println(var1)
//The specified position special value only traverses tuples starting with 1
for((1,_) <- List((1,2),(3,5)))
	println(var1)

Matching objects and sample classes

object User{
 def apply(name: String, age: Int): User = new User(name, age)
 def unapply(user: User): Option[(String, Int)] = {
 if (user == null)
 None
 else
 Some(user.name, user.age)
 }
}
object TestMatchUnapply {
 def main(args: Array[String]): Unit = {
 val user: User = User("zhangsan", 11)
 val result = user match {
 case User("zhangsan", 11) => "yes"
 case _ => "no"
 }
 println(result)
 }
}

When User("zhangsan", 11) is written after case [case User("zhangsan", 11) = > "yes"], the unapply method (object extractor) will be called by default. User is used as the parameter of the unapply method. The unapply method extracts the name and age attributes of the user object and matches the attribute values in User("zhangsan", 11)

If the unapply method (extractor) of the object in case returns Some and all attributes are consistent, the matching is successful. If the attributes are inconsistent or return None, the matching fails.

Sample class

case class Person (name: String, age: Int)

○ 1 the sample class is still a class. Compared with ordinary classes, it only automatically generates associated objects, and some common methods are automatically provided in the associated objects, such as apply, unapply, toString, equals, hashCode and copy.

○ 2 the sample class is optimized for pattern matching, because it provides the unapply method by default. Therefore, the sample class can directly use pattern matching without implementing the unapply method by itself.

○ 3 every parameter in the constructor becomes val unless it is explicitly declared as var (this is not recommended)

Pattern matching in partial function (understanding)

The function is to return the second element of the input List set

Chapter 8 implicit transformation

exception handling

def main(args: Array[String]): Unit = {
 try {
 var n= 10 / 0
 }catch {
 case ex: ArithmeticException=>{
 // Arithmetic exception occurred
 println("Arithmetic exception occurred")
 }
 case ex: Exception=>{
 // Exception handling
 println("Exception 1 occurred")
 println("Exception 2 occurred")
 }
 }finally {
 println("finally")
 }
}

Use the throw keyword to throw an exception object. All exceptions are subtypes of Throwable. Throw expressions are typed, which is Nothing

When the compiler fails to compile for the first time, it will find the method that can make the code compile in the current environment, which is used to convert the type and realize secondary compilation

implicit function

class MyRichInt(val self: Int) {
 def myMax(i: Int): Int = {
 if (self < i) i else self
 }
 def myMin(i: Int): Int = {
 if (self < i) self else i
 }
}
object TestImplicitFunction {
 // Functions declared with the implicit keyword are called implicit functions
 implicit def convert(arg: Int): MyRichInt = {
 new MyRichInt(arg)
 }
def main(args: Array[String]): Unit = {
 // When you want to call an object function, if the compilation is wrong, the compiler will try to be in the current scope
 Find the conversion rule that can call the corresponding function within the scope. This calling process is completed by the compiler, so it is called implicit
 Type conversion. Also known as automatic conversion
 println(2.myMax(6))
 }
}

Implicit parameter

Parameters in ordinary methods or functions can be declared as implicit parameters through the implicit keyword. When the method is called, the parameter can be passed in, and the compiler will find qualified implicit values in the corresponding scope.

(1) There can only be one implicit value of the same type in the same scope

(2) The compiler looks for the implicit value of the corresponding type according to the type of implicit parameter, which has nothing to do with the name of the implicit value.

(3) Implicit parameters take precedence over default parameters

object TestImplicitParameter {
 implicit val str: String = "hello world!"
 def hello(implicit arg: String="good bey world!"): Unit = {
 println(arg)
 }
 def main(args: Array[String]): Unit = {
 hello
 }
}

Implicit class

Implicit classes must be defined in "class" or "companion object" or "package object", that is, implicit classes cannot be top-level.

object TestImplicitClass {
 implicit class MyRichInt(arg: Int) {
 def myMax(i: Int): Int = {
 if (arg < i) i else arg
 }
 def myMin(i: Int) = {
 if (arg < i) arg else i
 }
 }
 def main(args: Array[String]): Unit = {
 println(1.myMax(3))
 }
}
implicit var a = 1
    
    def myTest():Unit = {
      println("---"+ implicitly[Int])
    }

generic paradigm

class MyList[+T] {/ / covariant}

class MyList[-T] {/ / inversion}

class MyList[T] / / unchanged

Description covariance: if Son is a subclass of Father, MyList[Son] is also a "subclass" of MyList[Father].

Inversion: if Son is a subclass of Father, MyList[Son] is the "parent" of MyList[Father].

Unchanged: if Son is a subclass of Father, MyList[Father] and MyList[Son] have "no parent-child relationship".

Generic upper and lower bounds

Class personlist [T <: person] {/ / Generic upper limit}

Class personlist [t >: person] {/ / generic lower limit}
Int): MyRichInt = {
new MyRichInt(arg)
}
def main(args: Array[String]): Unit = {
//When you want to call an object function, if the compilation is wrong, the compiler will try to be in the current scope
Find the conversion rule that can call the corresponding function within the scope. This calling process is completed by the compiler, so it is called implicit
Type conversion. Also known as automatic conversion
println(2.myMax(6))
}
}

##  Implicit parameter

Parameters in ordinary methods or functions can be implicit Keyword is declared as an implicit parameter. When the method is called, the parameter can be passed in, and the compiler will find the qualified implicit value in the corresponding scope.



(1)There can only be one implicit value of the same type in the same scope 

(2)The compiler looks for the implicit value of the corresponding type according to the type of implicit parameter, which has nothing to do with the name of the implicit value. 

(3)Implicit parameters take precedence over default parameters

```scala
object TestImplicitParameter {
 implicit val str: String = "hello world!"
 def hello(implicit arg: String="good bey world!"): Unit = {
 println(arg)
 }
 def main(args: Array[String]): Unit = {
 hello
 }
}

Implicit class

Implicit classes must be defined in "class" or "companion object" or "package object", that is, implicit classes cannot be top-level.

object TestImplicitClass {
 implicit class MyRichInt(arg: Int) {
 def myMax(i: Int): Int = {
 if (arg < i) i else arg
 }
 def myMin(i: Int) = {
 if (arg < i) arg else i
 }
 }
 def main(args: Array[String]): Unit = {
 println(1.myMax(3))
 }
}
implicit var a = 1
    
    def myTest():Unit = {
      println("---"+ implicitly[Int])
    }

generic paradigm

class MyList[+T] {/ / covariant}

class MyList[-T] {/ / inversion}

class MyList[T] / / unchanged

Description covariance: if Son is a subclass of Father, MyList[Son] is also a "subclass" of MyList[Father].

Inversion: if Son is a subclass of Father, MyList[Son] is the "parent" of MyList[Father].

Unchanged: if Son is a subclass of Father, MyList[Father] and MyList[Son] have "no parent-child relationship".

Generic upper and lower bounds

Class personlist [T <: person] {/ / Generic upper limit}

Class personlist [t >: person] {/ / generic lower limit}

Keywords: Java Scala Programming Big Data

Added by Iconoclast on Thu, 17 Feb 2022 05:15:33 +0200