1.Kotlin
1.1 kotlin's position in Android
Since the birth of Android, it has only provided Java as a language to develop applications
At the I/O conference in 2017, Google announced that Kotlin, as the first-class development language of Android, is on an equal footing with Java
At the I/O conference in 2019, Google announced that Kotlin has become the first development language. Of course, Java development is still useful
So far, in the foreign Android Market, the vast majority of apps have been developed using Kotlin.
Some official videos and open source projects of Google use Kotlin, and Kotlin is becoming more and more important.
1.2 historical process of kotlin
In 2011, JetBrains released the first version of Kotlin
2012 Kotlin open source
In 2016, Kotlin released the official version of 1.0, and IDEA also supports the use of Kotlin
In 2017, Google announced that Kotlin became the first-class language of Android
In 2019, Google announced that Kotlin became the first language of Android
1.3 programming language
programing languageeffectlanguageProgramming languageThe compiler compiles the source code we write into binary that can be recognized by the computer at one time and runs it directlyC,C++Interpretive languageThe interpreter will read the source code line by line, interpret these source codes into binary data in real time, and then execute them. The efficiency will be poorPython,JavaScript2 variables and functions
2.1 variables
Kotlin is very different from Java variables
Java: integer variable (int a), string variable (String b)
Kotlin defines variables in only two keyword declarations
val(value abbreviation) is used to declare an immutable variable, that is, after the initial assignment, the variable can no longer be modified, corresponding to the Java final variable
var(variable abbreviation) is used to declare a variable, that is, after the initial assignment, the content of the variable can also be changed. Non final variables corresponding to Java
After Kotlin writes a line of code, semicolons are not required; , and Java is required, so you need to pay attention when changing java to Kotlin
var a = 10 //Automatically declared as int type data var b = "How do you do" //Automatically declare as string type data
In Kotlin, var or val is used to define variables for any type of data, because it will automatically identify what type of data it is. This is Kotlin's type derivation mechanism. However, if our variable is delayed assignment, it cannot be deduced automatically. At this time, we need to explicitly declare the type of the variable
//When a variable is explicitly declared, the Kotlin derivation mechanism will not deduce the variable. When you try to assign a String to a, an exception will be thrown var a:Int = 10Java basic data typeKotlin object data typedata typeintIntintegerlongLongLong integershortShortShort floatFloatSingle precision floating pointdoubleDoubleDouble precision floating pointbooleanBooleanBooleancharCharcharacterbyteByteByte type
In Java, few people will take the initiative to use final, which leads to the fact that they don't know where this variable has been modified in the later stage, which leads to the increase of the insertion cost. In Kotlin, when defining a variable at the beginning, you must define whether it is var or val, and actively declare whether the variable can be changed.
Aunt Guo said that val (immutable variable) should be used first. When you need to change the variable later, change Val to var
2.2 function
Methods and functionsIn fact, there is no difference between methods and functions, but the names are different. They are function and method translated from English. Methods are often called in Java and functions are often called in Kotlin
//Use the fun keyword to define a function //methodName is the name of the defined function //(the parameters in parentheses are the accepted parameters. Any number (can be empty). This example is two parameters of Int type) //Format: parameter name (optional): parameter type //After (): Int is to declare that the function is to return Int type data //Inside {} is the function body fun methodName(param1: Int, param2: Int): Int{ //Standard function return 0 }Grammar sugar
Kotlin allows us to write the only line of code at the end of the function definition without writing the function body, and use the equal sign connection in the middle
//Primitive function fun largerNumber(num1: Int, num2: Int): Int{ return max(num1, num2) } //The returned integer data is an integer data returned by the max function after passing in the max function. Since there is only one line, the function body is not allowed to be written fun largerNumber(num1: Int, num2: Int): Int = max(num1, num2)
3. Logic control of program
There are three kinds of program execution statements: sequential statements, conditional statements and circular statements
Sequential statement: as the name suggests, execute code line by line in order
There are only two kinds of conditional statements, one is if statement, the other is when statement
Loop statement: as the name suggests, there are two kinds of loop statements, one is the while loop and the other is the for loop
3.1if conditional statement
fun largerNumber(num1: Int, num2: Int): Int{ var value = 0; if(num1 > num2){ //If num1 is greater than num2, get num1 value = num1 } else { //Otherwise, get num2 value = num2 } return value //To return the obtained number is actually to return the maximum number } //Simplified writing fun largerNumber(nuum1: Int, num2: Int): Int{ val value = if(num1 > num2){ num1 } else { num2 } return value } //Simplified writing fun largerNumber(num1: Int, num2: Int): Int{ return if(num1 > num2){ num1 } else { num2 } //Simplified writing fun largerNumber(num1: Int, num2: Int) = if(num1 > num2){ num1 } else { num2 } //The simplest way to write fun largerNumber(num1: Int, num2: Int) = if(num1 > num2) num1 else num2
3.2 when conditional statement
It is similar to the switch in Java, but it does not need to add a break after each case, just write the required logic.
The when statement allows any type of parameter to be passed in, and a series of conditions can be defined in the when structure
Match value - >
The following is how to write the if statement
fun getScore(name: String) = if(name == "Tom"){ 86 } else if(name == "Jim") { 77 } else if(name == "Jack") { 95 } else if(name == "Lily"){ 100 } else { 0 } //Concise writing, using when conditional statements fun getScore(name:String) = when (name){ "Tom" -> 86 "Jim" -> 77 "Jack" -> 95 "Lily" -> 100 else -> 0 }
The when statement allows type matching
//Number is a subclass of Int, Long, Float, Double and other number related classes fun checkNumber(num: Number) { when (num) { //The is keyword is equivalent to Java instanceof is Int -> println("is Int") is Double -> println("is Double") else -> println("not support") } }
How to use parameters without transmission
//Sometimes you may need to put the expression into the judgment separately, which is suitable for separate judgment fun getScore1(name: String) = when { name.startsWith("Tom") -> 86 //The name begins with Tom name == "Jim" -> 77 name == "Jack" -> 95 name == "Lily" -> 100 else -> 0 }
3.3 circular statements
The while method is the same as Java
//When the Boolean expression of while (Boolean expression) is false, the loop exits //The biggest difference between while and do... while is that while judges the expression before deciding whether to loop, while do....while judges the expression before deciding whether to loop, so it should loop at least once fun getWhile() { var i = 10 while (i > 0) { println("i is $i") i -= 1 } var y = 10 do { println("y is $y") y -= 1 } while (y > 0) }
for loop statement
Kotlin's loop statement has only a for - in loop
Simpler than for-i, but less flexible than for-i
//Interval: and includes 0 and 10, mathematical expression: [0,10] val range = 0..10 //Interval, left closed and right open, including 0 and excluding 10. Mathematical expression: [0,10) val range = 0 until 10 fun forIn(){ //Output 0 - 10 for (i in 0..10){ println(i) } //Output 0-9 for (i in 0 until 10){ println(i) } //Cycle the number of 0-9, but increase 2 each time //step keyword, which is equivalent to i = i+2 in Java for (i in 0 until 10 step 2){ println(i) } //Flashback, 10 starts to drop to 1, and the downTo keyword can be used with step for (i in 10 downTo 1){ print(i) } }
4 object oriented programming
4.1 object oriented, class and object
Like Java, Kotlin is an object-oriented language
Object oriented can create classes. A class is the encapsulation of a thing or thing into a class. The class name is usually a noun, and the class also has its own fields and functions. Fields are the attributes and functions.
Classes and objects
An object is actually an instance object of a class. In short, I define a "firewood" class (this is an animal)
"Xiao Chai" has age, name and behavior. He can eat, eat() and sleep()
Then I define a "Xiaochai" instance object, that is, I have a pet of Xiaochai. His name is Memory. He was just born and only 1 year old. He can eat() and sleep()
4.2 inheritance and constructor
In Kotlin, classes are not inheritable by default. If they need to be inherited by a class, the class must be preceded by open. In this way, the subclass can use the methods and variables of the parent class
//Inherited class open class Person{ ...... } //Inherited class class Student : Person(){ //The inherited class here needs to add () because it involves the primary constructor. The primary constructor and secondary constructor are a little different from those in Java }
Constructor in Java
public class Student{ public Student(){ } public Student(int age, String name){ } }
Kotlin's is special, which is divided into primary constructor and secondary constructor
The main constructor will be your most commonly used constructor. Each class will default to a main constructor without parameters. You can indicate its parameters. The main constructor has no function body and can be defined directly after the class name
//The Person() here is actually calling the Person constructor Person() class Student(val sno: String, val grade: Int) : Person(){ //init constructor and the logic of the main constructor can be written here (but this is not the best way, and it is generally not used in this way) init{ println("sno is " + sno) println("grade is "+ grade) } }
Secondary constructor
You can hardly use the secondary constructor. Kotlin provides a function to set the default value of parameters, which can basically replace the function of the secondary constructor. A class can only have one primary constructor and multiple secondary constructors. A secondary constructor can instantiate a class, but it has a function body. (that is, if you want to omit a variable, you can set the default value in the main constructor. After setting, you can use the main constructor to create it without adding the variable)
class Student(var){ }
When a class has both primary and secondary constructors, all secondary constructors must call the primary constructor (including indirect calls)
//The age and name here cannot be set to val because they will conflict with the age and name of the parent class. Without them, the scope is only in the main constructor class Student(val sno:String, val grade: Int, name: String, age: Int) :Person(name, age) { //Define the secondary constructor through the constructor keyword constructor(name: String, age: Int):this("", 0, name, age){ } constructor() : this("", 0){ } } //This is the creation of a secondary constructor without a primary constructor. There is no primary constructor, so there is no need to add parentheses when inheriting Person class Student : Person{ constructor(name:String, age: Int) : super(name, age){ } }
4.3 interface
The interface is almost the same as that of Java
A class can implement multiple interfaces
//Interface interface Study{ fun readBooks() fun doHomework() } //Class implements interfaces, separated by commas class Student(name: String, age: Int) : Person(name, age), Study{ //override keyword overrides or implements an interface function override fun readBooks(){ println(name + " is reading.") } override fun doHomework(){ println(name + " is doing homework.") } } //Interface 2 interface Study{ fun readBooks() fun doHomework() { //In this case, when implementing the Study interface, the doHomework() method may not be implemented. If it is not implemented, it means that the method is effective. The rewritten method shall prevail println(name + " is doing homework.") } }
4.4 modifiers
Modifier JavaKotlinpublicAll classes visibleAll classes visible (default)privateThe current class is visibleThe current class is visibleprotectedThe current class, subclass and classes under the same package path are visibleThe current class and subclass are visibledefaultClasses under the same package path are visible (default)nothingprotectednothingClass visible in the first mock exam module4.5 data class and singleton class
In Java, data classes usually need to override the equals(), hashCode(), toString() methods
The Kotlin implementation is simple
//When the data keyword is used, the equals(), hashCode(), toString() methods will be automatically generated for you according to the parameters of the main constructor data class Person(val country: String, val sex: String)
Method of creating singleton in Java
//Singleton creation public class Singleton{ private static Singleton instance; private Singleton(){} public synchronized static Singleton getInstance(){ if(instance == null{ instance = new Singleton(); } return instance; } public void singletonTest(){ System.out.println("singletonTest is called.") } } //Use of singleton Singleton singleton = Singleton.getInstance(); singleton.singletonTest();
Method of creating singleton in Kotlin
//It's that simple. This is a singleton pattern //You don't need to provide any method to create, just change the class keyword to the object keyword, because Kotlin will automatically help you create a Singleton instance to ensure that there is only one instance in the world object Singleton{ //Add a function in singleton mode fun singletonTest(){ println("singletonTest is called.") } } //The use method of singleton is similar to the calling method of static method in Java Singleton.singletonTest()
4.6 lambda programming
Sets are mainly divided into three types: List, Set and Map
The main implementation classes of List are ArrayList and LinkedList
The main implementation class of Set is HashSet
The main implementation class of Map is HashMap
//Create an ArrayList instance val list = ArrayList<String>() list.add("Apple") list.add("Banana") list.add("Pear") //Use the listOf() function to simplify initialization writing //However, the set created by listOf is immutable, that is, after creation, it can no longer be changed. It can only be read and cannot be changed val list = listOf("Apple", "Banana", "Pear") //loop for(fruit in list){ println(fruit) } //This is the list initialization method that can be modified val list = mutableListOf("Apple", "Banana", "Pear") list.add("Orange") //The usage of Set is almost the same as that of List, except that it is changed to setOf() and mutableSetOf() val set = setOf("Apple", "Banana", "Pear") val set = mutableSetOf("Apple", "Banana", "Pear") //The usage of Map is quite different from that of List and Set //The first use of Map val map = HashMap<String, Int>() map.put("Apple", 1) map.put("Banana", 2) map.put("Pear", 3) //The second use of Map val map = HashMap<String, Int>() map["Apple"] = 1 map["Banana"] = 2 map["Pear"] = 3 //The simplest use of Map val map = mapOf("Apple" to 1, "Banana" to 2, "Orange" to 3, "Pear" to 4) //loop for((fruit, number) in map){ prinltln("fruit is " + fruit + ", number is " + number) }
Collection's functional API
val list = listOf("Apple", "Banana", "Pear") val maxLengthFruit = list.maxBy //Get the longest fruit
Lambda expression:
Lambda expression. You can edit any line of code, but it is not recommended to be too long. The last line will be automatically used as the return value of lambda expression
The above is a code segment, which is reduced to one sentence because of Kotlin's characteristics
val list = listOf("Apple", "Banana", "Pear") val lambda = val maxLengthFruit = list.maxBy //Get the longest fruit //Simplified version val maxLengthFruit = list.maxBy() //Kotlin stipulates that when the Lambda parameter is the last parameter of the function, you can move the Lambda expression outside the parentheses val maxLengthFruit = list.maxBy() //Lambda parameter is the only parameter of the function, and parentheses can be omitted val maxLengthFruit = list.maxBy //Kotlin derivation mechanism, String type declaration can be omitted val maxLengthFruit = list.maxBy //When a Lambda expression has only one parameter, you can use the it keyword instead val maxLengthFruit = list.maxBy
The map function maps the elements in the collection to other values, and the rules are specified in Lambda
val newList = list.map{"Code block"}
The filter function is used to filter the elements in the collection when the condition is the code in Lambda
//Keep fruit within 5 characters val newList = list.filter{ it.length <= 5}
The any function returns true as long as one of the elements in the collection is satisfied, and false if none is satisfied
The all function returns true only if all elements in the collection are satisfied. Otherwise, it returns false as long as one element is not satisfied
//Returns true whenever the length of a fruit is less than 5 val newList = list.any{ it.length <= 5} //false is returned as long as one fruit is not less than 5 val newList = list.all{ it.length <= 5}
4.7 using Java's functional API in Kotlin
The Java method is invoked in Kotlin, and the method accepts a Java single abstract method interface parameter, so function API can be used.
A single abstract method means that there is only one method to be implemented in the interface
Example: Runnable interface
//Runnable interface public interface Runnable{ void run(); } //Usage of using Runnable interface new Thread(new Runnable(){ @Override public void run(){ System.out.println("Thread is running"); } }).start();
//Usage of Kotlin using Runnable interface //Use the object keyword to create an anonymous class Thread(object : Runnable{ override fun run(){ println("Tread is running") } }).start() //Shorthand method of functional API //When there is only one method to be implemented, Kotlin can automatically understand that the Lambda expression inside is the implementation content of the run() method Thread(Runnable{ println("Thread is running") }).start() //When more than one Java single abstract method interface parameter does not exist in the parameter list of Java method, we can also omit the interface name Thread({ println("Thread is running") }).start() //When the Lambda expression is the last parameter of the method, you can move the Lambda expression outside the parentheses. At the same time, the expression is the only parameter, and the parentheses can be omitted Thread{ println("Thread is running") }.start();
Although we all use Kotlin to write code now, we need to deal with the Android SDK often, and it is still written in Java. For example, the listening event of Button
button.setOnClickListener{ }
4.8 null pointer
I believe that when writing Android, null pointer exceptions have been removed more or less. In Java, when there may be null data, we have to judge null. Kotlin has a null checking mechanism, which uses null checking during compilation, so as to almost prevent null pointer exceptions.
However, this may make the code more troublesome, but Kotlin provides a set of tools to make it easy for us to judge null
///In this case, if you pass a null, an error will be reported when compiling because a null pointer appears doStudy(null) //Air transmission fun doStudy(study:Study){ study.readBooks() study.doHomework() }
In this case, we will report an error as long as we pass it empty, but sometimes we need to pass it empty, so we need a question mark. Add "null" after the data type? This means that the data can be null
Int? Represents nullable integer data String? Represents nullable data,
//At this time, there will be no error in the air doStudy(null) //Air transmission fun doStudy(study:Study?){ study.readBooks() study.doHomework() }
Although it can be null passed, the two methods inside will certainly report null pointer exceptions, because they must have data to execute. At this time, we can write like Java
fun doStudy(study:Study){ if(study != null){ study.readBooks() study.doHomework() } }
But if it is written in this way, it has no advantage and is very troublesome
You can use it here The meaning of this symbol means that when the object is not empty, it will be called, and when the object is empty, it will not be executed
This code is equivalent to Java
if(a != null){ a.doSomething() }
It can be used in Kotlin like this Symbols to simplify code
//a is there an object? If yes, execute the doSomething() method. If not, skip and do not execute a?.doSomething()
?: Operator. If both sides of the operator are expressions, the result of the expression on the left will be returned if the result of the expression is not empty, otherwise the result of the expression on the right will be returned.
//If a is not empty, then c = a; Otherwise c = b val c = a ?: b //Original writing fun getTextLength(text: String?): Int{ if(text != null){ return text.length } return 0 } //use?. And?: Writing method of //When text is empty, do not execute the length method, return a null, and then use?: Judge whether the right side is null, and return a 0 if it is, fun getTextLength(text: String?) = text?.length ?: 0
Although there is a null pointer checking mechanism, sometimes it fails
fun main(){ if(content != null){ printUpperCase() } } //Although it is judged to be empty outside, it will re judge whether the variable may be empty inside the method, because the method does not know that it has been judged to be empty in the external main function, so it can only judge whether it is empty fun printUpperCase(){ val upperCase = content.toUpperCase() } //You can use force compilation Symbol, but this way of writing is risky, because we need to ensure that it will not be empty, otherwise we will report an error and flash back val upperCase = content!!.toUpperCase()
Let function, using the method. Here is the let function that calls the obj object, and then the code in the Lambda expression will be executed by science, and the obj object will be passed into the expression. Here, obj and obj2 are actually the same object. This function can be used in conjunction with the null checking mechanism
obj.let{ obj2 -> //Write specific code } //Original code //In fact, this is equivalent to judging if (study! = null) {} twice, each Judge once fun doStudy(study: Study?){ study?.readBooks() study?.doHomework() } //Used with let, this code means that the let function is executed as long as study is not empty //The let function passes the study object into the Lambda expression fun doStudy(study: Study?){ study?.let{ stu -> stu.readBooks() stu.doHomework() } } //simplify fun doStudy(study: Study?){ study?.let{ it.readBooks() it.doHomework() } }
When the study object is a global variable, the if statement will still report an error, such as
var study: Study? = null fun doStudy(){ if(study != null){ study.readBooks() study.doHomework() } }
But let function can deal with the problem of global empty judgment
4.9 string embedded expression
Kotlin string inline expression
// The ${} expression can kick part of the content "hello, $. nice to meet you!" //When there is only one variable, {} can also be omitted "hello, $name . nice to meet you!" //println("my name is " + name + ", my age is " + age) //println("my name is $name, my age is $age")
4.10 default values of function parameters
Kotlin provides the function to set the default value of parameters
Because of this function, secondary constructors are rarely used
fun printParams(num: Int, str: String = "hello"){ println("num is $num, str is $str") } //The second parameter of the above function is the default value, so when we use it, we can only pass one Int parameter fun main(){ printParams(12345) } //When setting the default value for the first fun printParams(num: Int = 100, str: String){ println("num is $num, str is $str") } //Wrong use, this will report an error printParams("hello") //Can't it be used like this? No, the Kotlin mechanism also passes parameters through key value pairs printParams(str = "world", num = 123) printParams(str = "world") //It is this method. Therefore, the main constructor adds multiple parameters. Different methods use the main constructor to create objects