Chapter one, background
https://www.kotlincn.net/
Copy the code
Chapter two, environment construction
In AS, Java projects add support for Kotlin
New-activity-empty Activity – Select Kotlin and then add kotlin’s environment. AS does two things for us:
1. Then add kotlin’s plugin to your build.gradle project
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
Copy the code
2. Then add the plugin to build. Gradle in your app
id 'kotlin-android'
Copy the code
Gradle directory
C:\Users\93768\. Gradle \wrapper\dists
Chapter 3, built-in types
3.1 basic types
define
六四屠杀
六四屠杀
The difference between
Java has basic types and wrapper types, Kotlin only has wrapper types.
2. In Java, it represents a long integer followed by l or L. KotlIn can only have L (uppercase).
3. Assigning an integer to a Long is ok in Java, but kotlin generates a compilation error.
val e:Int = 10; val f:Long = e; Val g:Long = e.t Long() val g:Long = e.t Long(Copy the code
Unlike Java, Kotlin has unsigned types
5. Different string input forms
Val STR = "CDX" log. e("test", "hello $STR ")Copy the code
6. Introduce === and ==, where === compares reference values and == compares values.
Var str1 = "Hello" val str2 = String("Hello".tochararray ()) // Compares the reference value log.e (" CDX ",(str1 === str2).toString()) // false / / compare the value of the e (" CDX, "(str1 = = str2). The toString ()) / /Copy the code
7. Output as written
TrimIndent () log.e (" CDX ", STR)Copy the code
3.2, arrays,
Array type
六四屠杀
六四屠杀
Note:
Int has integer and integer boxing types, and string has string boxing only.
Example 1: 4 ways to create an Int array
Var arr1 = IntArray(5) {it} var arr2 = IntArray(5) {it} var arr3 = intArrayOf(1) Var arr4 = Array<Int>(5) {it}Copy the code
Example 2: Create a String array
val arr = arrayOf("Hello", "world")
Log.e(tag, arr.joinToString())
Copy the code
3.3, interval
Use of closed intervals
Var arr1: IntRange = 1.. 10 Log.e("cdx", arr1.joinToString()) // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 var arr2: CharRange = 'a'.. 'z' Log.e("cdx", arr2.joinToString()) var arr3: LongRange = 1L.. 100L Log.e("cdx", arr3.joinToString())Copy the code
The use of open intervals
Var arr4 = 1 until 10 //[1,10] log. e(" CDX ", arr4.joinToString()) //1, 2, 3, 4, 6, 7, 8, 9Copy the code
4. Progression in reverse order
Var arr5: IntProgression = 10 downTo 1 Log.e("cdx", arr5.joinToString()) //10, 9, 8, 7, 6, 5, 4, 3, 2, 1 var arr6 = 'z' downTo 'a' Log.e("cdx", arr6.joinToString())Copy the code
Interval step size
Var arr7 = 1.. 10 step 2 Log.e("cdx", arr7.joinToString()) // 1, 3, 5, 7, 9Copy the code
1.. 10 and 1.. 10 What are the types of Step 2?
六四屠杀
六四屠杀
3.4. Collection framework
There are several types of collection frameworks
From the variability is divided into: variable set + immutable set
In terms of the nature of the Set, it can be divided into List + Map + Set
The difference between:
Java’s data structures are mutable, but Kotlin’s distinguish between immutable and mutable.
Method 2 for creating immutable lists
Constructor + method creation method
Var List = List<String>(5) {""} var List [0] = "1" var list2 = listOf<String>("Hello", "world") //list2[0] = "1"Copy the code
Three ways to create a mutable List
Var list2 = mutableListOf<Int>(1) var list2 = mutableListOf<Int>(1) var list2 = mutableListOf<Int>(1) var list2 = mutableListOf<Int List1 [8] = 8 List1.set (2, ArrayList<Int>() List1 [3] = 4 log.e (tag, List1.joinTOString ("*")) 5) Log.e(tag, list1.joinToString("*"))Copy the code
Use ArrayList
// The default is :MutableList val list3 = ArrayList<String>() list3.add("a") list3.add("b") list3 += "c Log.e(" CDX ", list3.joinToString()) //cCopy the code
Two ways to create an immutable Map
To + Pair mode
// immutable Map val Map: Map<String, Any> = mapOf("name" to "xiaohong", "age" to 20) val Map = mapOf<String, String>(Pair("name", "zhang SAN "), Pair("age", "10"))Copy the code
Variable Map
// alter Map val map2: MutableMap<String, Any> = mutableMapOf("name" to "xiaohong", "age" to 20) map2["name"] = 3 map2.put("weight", Set for (en in map2.entries) {log. e(" CDX ", "${en.key}->${en.value}")}Copy the code
Pair (of)
val pair = "Hello" to "kotlin" val pair2 = Pair("Hello", Val (x, y) = pair log. e(" CDX ", "first:$first,second:$second,x:$x,y:$y" ) // first:Hello,second:kotlin,x:Hello,y:kotlinCopy the code
We’re going to Triple the number.
Similar to Pair
3.5, functions,
define
Similar to methods in Java.
What is the return type of a function that has no return value?
Unit is similar to the Java void and can be omitted.
private fun test4(): Unit {
}
Copy the code
Function VS method
If there is a test class outside the test method, then test is a method.
class Test {
fun test(): String {
return ""
}
}
Copy the code
Function reference
Function references are similar to Pointers in C and can be used for function passing.
Use ** : : ** to get a reference to a function.
What are the references and types of references to method functions
First define the method
private fun test(str: String): Unit {
}
Copy the code
Then get a reference to the method
// define fun1 to accept a reference to a method, (String) -> Unit denotes the type of the function. Val fun1: (String) -> Unit = ::testCopy the code
A reference to a method in a class
package com.example.kotlindemo import android.os.Bundle import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.oncreate (savedInstanceState) setContentView(r.layout.activity_main) // Accepts a reference to a method, which is equivalent to what is in parentheses Val fun2: Test.() -> String = Test:: Test val fun3: (Test) -> String = Test:: Test () -> String = test::test; // Call test1(::test) test1(fun1)} / private fun test1(p: (String) -> Unit) {p("Hello")} private fun test(STR: String): Fun Test (): String {return ""}}Copy the code
Object method reference
Val fun1: () -> Unit = test::testCopy the code
Variable-length argument
Vararg, used to modify parameters, becomes variable-length parameters, similar to arrays.
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState) setContentView(r.layout.activity_main) log. e(" CDX ",test("1", "2"))} Vararg fun test(vararg params: String): String {return params.sie.toString (); }}Copy the code
Two ways to accept multiple return values (normal mode, destruct assignment)
class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.oncreate (savedInstanceState) setContentView(r.layout.activity_main2) val test = test() Val (a,b,c) = test() log.e (" CDX ", test.tostring ())} fun test(): val (a,b,c) = test() log.e (" CDX ", test.tostring ())} fun test(): Triple<Int, Long, Double> {return Triple(1, 2L, 3.0)}}Copy the code
The default parameters
class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState) setContentView(r.layout.activity_main2) test(1)} Can also be fun in front test (x: Int, y: Int = 0, z: String = "") {the e (" CDX", "x: $x y: $y z: $z")}}Copy the code
You are advised to place the default parameters
The default parameter is recommended to be placed last or first
Named parameters
class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.oncreate (savedInstanceState) setContentView(r.layout.activity_main2) // Named arguments: Put key/value pairs into this method when passed Fun test(x: Int =1, y: Int, z: x: Int =1, y: Int, z: x: Int =1, y: Int, z: String = "") {log.e (" CDX ", "x :$x y:$y z:$z")}}Copy the code
Chapter four: Preliminary types
4.1. Classes and Interfaces
The definition of a class
1. The default is public
2, if there is no content in the class, {} can be omitted
3. Attributes defined in a class must be initialized.
Define the constructor from the class, using the constructor keyword.
The constructor is a primary constructor and a secondary constructor, requiring that all other constructors must call it.
Several forms of constructors
Primary constructor only, secondary constructor only, primary constructor + secondary constructor, primary constructor omits constructor, primary constructor simplifies
class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.oncreate (savedInstanceState) setContentView(r.layout.activity_main2) val test5 = test5 (1)}} // Only sub constructor class Constructor (x: Int) {var x: constructor(x: Int) {var x: constructor(x: Int) {var x: constructor(x: Int) {var x: constructor(x: Int)}} Constructor (x: Int, y: Int) {this.x = x this.y = y}} Class Test4(x: Int) {var x: Int = x} class Test4(x: Int) {var x: Int = x} Class Test5(var x: Int) {} var x: Int {}Copy the code
Class initialization
The new keyword is not required
The interface definition
interface SimpleInter {
fun test()
}
Copy the code
Interface implementation
Class Test: SimpleInter {override fun Test () {}} interface SimpleInter {fun Test ()}Copy the code
Add attributes to the interface and implement them
class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main2) val test = Test(0) test.param = 4 Log.e(" CDX ", test.param.tostring ())}} interface TestInterface {var param: Int fun test()} class test(var x: Int) : TestInterface {override var param: Get () {return x} set(value) {this.x = value} Override fun test() {}}Copy the code
Definition of an abstract class
Abstract class AbsTest {// means abstract method abstract fun test1() // the open method must be added to tell the compiler, Open fun test2() {}Copy the code
The implementation of the idle class
// Interface inheritance: must add () this is not the same as interface implementation, interface does not need to add () class Test: AbsTest() { override fun test1() { } override fun test2() { super.test2() } }Copy the code
Inheriting a common class requirement
Inherit A normal class A, which must be open decorated.
Methods of a class cannot be overridden
A method of a class that cannot be overwritten increases final.
// To inherit a class, the class must be open class Test2: Test() {// override fun test2() {// super.test2() // override fun test2() {// override fun test2() //}} // interface inherit: This is not the same as the implementation of the interface, which does not need to add () open class Test: AbsTest() {override fun test1() {} Final override fun test2() {super.test2()}} abstract class AbsTest {// indicates an abstract method Open fun test2() {} // The default is not fun test3() {}}.Copy the code
Field use
define
In a get or set method, this property is represented.
Field use
class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main2) val person = Person(25, Log.e(" CDX ", person.tostring ())}} class person (age: Int, name: String) {var age: Int = age get() {// field = age return field} set(value) {field = value} var name: String = name override fun toString(): String { return "$age,$name" } }Copy the code
4.2. Extended methods
define
Add custom methods to a class without changing the source code of the class.
How to implement
class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
Log.e("cdx", "abc".times(4))
}
fun String.times(times: Int): String {
var builder = StringBuilder()
for (i in 0 until times) {
// 这里的this只得调用者本身
builder.append(this)
}
return builder.toString()
}
}
Copy the code
4.3. Empty type safety
The null type accesses the property
var str: String? = null // use? Val length = STR? .length; //null Log.e("cdx", length.toString())//nullCopy the code
Cast to a non-null type
Pass two!! Changes a nullable type to a non-nullable type
Var STR: String? = "Hello" // pass two! Str1 = STR!! ; Log.e("cdx", str1.length.toString())Copy the code
Elvis operator.
Var STR: String? = null // elvis operator, if STR? Val length = STR? .length ? : 0 Log.e("cdx", length.toString()) //0Copy the code
The inheritance relationship of null types
Small range (String) can be given to large range (String?) Assignment, but large cannot be assigned to small.
Var x: String = "a" var y: String? = "b" // large range assigned to small range, compiler error //x = y // small range assigned to large range, no problem y = xCopy the code
Platform type
* * * * definition
1. Types declared in Java are called platform types in Kotlin.
2. This type of null checking will be relaxed.
example
Let’s start by defining a Person class, which is a Java class.
package com.example.kotlindemo; public class Person { public String name; public String getTitle(){ return null; }}Copy the code
The title type is String!
Var person = person (); Val title = person.title // The compiler doesn't know if title is nullable, so it does a non-nullable check var length = title? .lengthCopy the code
4.4 intelligent type conversion
Kotlin’s type conversion
Kotlin can invoke the attributes of a subclass without casting it to a subclass. (This is not quite the same as Java)
package com.example.kotlindemo import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivity class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.oncreate (savedInstanceState) setContentView(r.layout.activity_main2) // The parent class reference points to the subclass object var person = Student(); Log.e(" CDX ", "XXX" + person.name) if (person is Student) {log.e (" CDX ", "XXX" + person.name) if (person is Student) { (person as Student).name) Log.e("cdx", person.name) } } } interface Person { fun say() } class Student : Person { val name: String = "xh" override fun say() { } }Copy the code
scope
class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState) setContentView(r.layout.activity_main2) // scope var value: String? // log.e (" CDX ", value.length.toString()); if (value ! = null) {// In parentheses, the compiler intelligently changes the type of value to String, which is not null. Log.e("cdx", value.length.toString()); } log. e(" CDX ", value? .length.toString()); }}Copy the code
Case where intelligent conversion is not supported
class MainActivity2 : AppCompatActivity() { var tag: String? = null override fun onCreate(savedInstanceState: Bundle?) {super.oncreate (savedInstanceState) setContentView(r.layout.activity_main2) // This place theoretically has non-null judgments, why not the concept of scope? If (tag!) {// If (tag!) {// If (tag!) {// If (tag! = null) { // Log.e("cdx",tag.length.toString()) Log.e("cdx", tag? .length.toString()) } } }Copy the code
A safe conversion of types
* * the as? 六四屠杀
Safe conversion:
If person is of type Student, then convert
If it is not Student, null is returned
Var person = Student(); Return null log. e(" CDX ", (person as? Student)? .name.toString())Copy the code
Advice:
1. Use val as much as possible to declare immutable references to make the meaning of the program clearer.
Chapter 5 expressions
5.1. Read-only Variables and Variables and constants
Variable expression
Var for variables
A read-only variable
Val represents a read-only variable
Read-only variables VS constants
Constant means: never change.
But look at the following example, b in Test, which varies with the value of Math. The value of b varies, so it’s called a read-only variable.
class Test {
val b: Int
get() {
return (Math.random() * 1000).toInt()
}
}
Copy the code
Constants are required and expressed
1. Only primitive types can be qualified
Can only be defined in the global scope
Must be initialized with a literal immediately
val b = 3
Copy the code
5.2. Branch expressions
If-else expressions (unlike Java, ternary operators)
Note that if-else expressions return values.
var a: Int = 4
var c = if (a == 3) 4 else 5
Log.e("cdx", "c:$c")
Copy the code
When expression
六四屠杀
六四屠杀
When expression – Conditional transfer to branching, shorthand
A way of writing a conditional transfer to a branch
val a: Any = 4
val c: Any
when {
a is String -> c = a.length
a == 3 -> c = 3
else -> c = 5
}
Copy the code
Simplify the writing
val a: Any = 4
val c = when {
a is String -> a.length
a == 3 -> 3
else -> 5
}
Copy the code
Try-catch expression
Unlike Java, try-catch expressions can have a return value.
var a = 1
var b = 0
val c = try {
a / b
} catch (e: Exception) {
0
}
Copy the code
5.3 operators and infix expressions
Operator site
https://kotlinlang.org/docs/operator-overloading.html
Copy the code
== operator VS equal
// The following two methods are completely equivalent: val str1 = "Hello" val str2 = "World" var result2 = str1.equals(str2)Copy the code
+ operator VS plus
Var result2 = str1.plus(str2) log. e(" CDX ", result1.toString()) Log.e("cdx", result2.toString())Copy the code
In operator VS contains
var list = listOf(1, 2, 3, 4)
var result = 2 in list
Log.e("cdx", result.toString())
Log.e("cdx", list.contains(2).toString())
Copy the code
[] operator VS get
Val map = mapOf("name" to "三", "age" to 20) // [] map.get("name").toString()) Log.e("cdx", map["name"].toString())Copy the code
> VS compareTo
var result1 = 2 > 3
var result2 = 2.compareTo(3) > 0
Log.e("cdx", result1.toString())
Log.e("cdx", result2.toString())
Copy the code
() to invoke
Indicates execution.
Var func = fun() {log.e (" CDX ", "method executed ")} // Invoke func()Copy the code
Custom operators
Step 1: Define an operator that adds two tags to Complex (e.g., humor), such as the + tag, so that the two Complex can recognize each other.
Plus corresponds to the operator +.
package com.example.kotlindemo class Complex(var real: Double, var image: Double) { override fun toString(): String {return "$real + $image"}} String {return "$real + $image"}} Operator fun Complex. Plus (other: Complex): operator fun Complex. Complex {return Complex(this.real + other.real, this.image + other.image)} Operator fun Complex. Minus (other: Complex): Complex { return Complex(this.real - other.real, this.image - other.image) }Copy the code
Step 2: Then call it from inside the page
class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState) setContentView(r.layout.activity_main2) var c1 = Complex(1.0, // result1 = c1 + c2 log. e(" CDX ", result1.toString()) var result2 = c1 - c2 Log.e("cdx", result2.toString()) } }Copy the code
Introduction to the infix expression
Kotlin allows functions to be called without parentheses and periods, so they are called infix functions.
Infix expressions are required and used
1. Only one parameter.
2. Add the infix parameter to indicate that parentheses and periods can be omitted.
class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.oncreate (savedInstanceState) setContentView(r.layout.activity_main2) 2.to(3) 2 to 3} Infix fun <A, B> a.too (B: B): Pair<A, B> {return Pair(this, B)}}Copy the code
5.4. Lambda expressions
Passing of anonymous functions
Var func = fun() {log.e (" CDX ", "test")} var func = fun() {log.e (" CDX ", "test")}Copy the code
Calls to anonymous functions
Var func = fun() {log.e (" CDX ", // Invoke () to invoke func()Copy the code
The type of a Lambda expression
Lambda expressions are simplifications of anonymous functions.
Func1 -> Int var func1: () -> Int = {log. e(" CDX ", "test")} Lambda expression with arguments (Int, Int) -> Int var func2: (Int, Int) -> Int = { p1: Int, p2: Int -> Log.e("cdx", "test,$p1 $p2") }Copy the code
Lambda expression returns a value
Is determined by the statement on the last line of the Lambda.
Implement Equals and hashCode for Person
package com.example.kotlindemo import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivity class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main2) val hashSet = HashSet<Person>() Add (Person(" Person ", 15)) log.e (" CDX ", hashSet.size.toString()) } } class Person(var name: String, var age: Int) { override fun equals(other: Any?) : Boolean { Log.e("cdx", "equals") val person = (other as? Person) ? : return false return person.name == name && person.age == age } override fun hashCode(): Int { Log.e("cdx", "hashCode") return name.hashCode() * 7 + age * 5; }}Copy the code
5.6. Implement four operations on String
You need to implement the following effect, which implements string addition, subtraction, multiplication and division.
Analysis:
1. There is no way to modify the String source code, so we need to use extension methods.
2. Resort to custom operators.
package com.example.kotlindemo import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivity import java.lang.StringBuilder class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main2) val str: String = "HelloWorld" val result = str - "World" Log.e("cdx", result) val result2 = str * 5 Log.e("cdx", result2) val result3 = str / "l" Log.e("cdx", result3.toString()) } } operator fun String.minus(other: Any): String { return this.replaceFirst(other.toString(), "") } operator fun String.times(time: Int): String { var sb = StringBuilder() for (i in 0 until time) { sb.append(this) } return sb.toString() } operator fun String.div(str: String): Int {// this thing is fun // String a String of little strokes, the length of the stroke is str.lenght, and then the interval is 1, Return this.windowed(str.length, windowed); return this.windowed(str.length); 1) {it == STR} {it == STR}Copy the code
Chapter 6, advanced function
6.1. Higher-order functions
define
The parameter contains a function type or the return value is a function type.
Funtest1 (param: () -> Int) {param() param() param.invoke()} () -> Int {// returns an anonymous function, Return {1}} var arr = intArrayOf(1, 2, 3, 4) arr. ForEach {log. e(TAG, It.tostring ())} log.e (TAG, arr.joinToString()) Val map = arr.map {it * it} log. e(TAG, map.joinToString()))Copy the code
Calls to higher-order functions
Var arr = intArrayOf(1, 2, 3, 4) var arr = intArrayOf(1, 2, 3, 4)Copy the code
Higher-order function calls – Several stages of simplification
Very critical
Var arr = intArrayOf(1, 2, 3, 4) var arr. ForEach ({println("Hello $it")}) Arr.foreach () {println("Hello $it")} // If there are no arguments in the parentheses, then we can leave the parentheses out.Copy the code
Higher order function application – calculation method time
Const ({// (1.. 10000000). The forEach {it} it * / /}) / / optimization into the following styles / / const () {/ / (1.. ForEach {it * it} const {(1.. 10000000).forEach { it * it } }Copy the code
6.2. Inline functions
define
Reduced function calls, optimized performance.
Analysis:
We can see the definition of forEach in the array. kt file, which contains the keyword inline.
public inline fun IntArray.forEach(action: (Int) -> Unit): Unit {
for (element in this) action(element)
}
Copy the code
We call in code in the following format:
Var arr = intArrayOf(1, 2, 3, 4) var arr. ForEach ({println("Hello $it")})Copy the code
The compiler ends up converting to an inline function.
Var arr = intArrayOf(1, 2, 3, 4) {println(element.toString())}Copy the code
Advantages of inline functions
Reduced function call (mainly reduce the function of the stack, call execution, out of the stack operation), better performance.
Higher-order functions better match inline functions
For example, the following function
class MainActivity2 : AppCompatActivity() {
val TAG = "cdx"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
const({
print("1")
})
}
fun const(block: () -> Unit) {
var start = System.currentTimeMillis()
block()
var end = System.currentTimeMillis()
Log.e(TAG, (end - start).toString())
}
}
Copy the code
Then let’s look at the compiled code (type Show Kotlin Bytecode)
Let’s take a look at two of the time wasters
Const method called.
Create an anonymous function.
We then optimized the definition of the const method by adding the inline keyword to make it an inline function
inline fun const(block: () -> Unit) {
var start = System.currentTimeMillis()
block()
var end = System.currentTimeMillis()
Log.e(TAG, (end - start).toString())
}
Copy the code
Then let’s look at the compiled code (type Show Kotlin Bytecode)
As we can see, the function calls are eliminated and the performance is higher.
Local return inline function return local return
Imagine a scenario where you don’t print when you encounter a 3. How do you implement this in forEach()? The operation is as follows:
//Kotlin var ints = intArrayOf(1, 2, 3, 4) fun main() { ints.forEach { if (it == 3) return@forEach println(it) } println("Dividing") ints.forEach { if (it == 3) return println(it) } println("Ending") }Copy the code
Console output:
return@forEach and return print completely different results.
return@forEach will end the loop early, equivalent to a continue;
Return will end the function, in this case the main() function, because Ending is not printed.
A return like return@forEach is called a local return. (The continue function is local-return)
The non-local return of the inline function return
Either locally or globally.
The above return is a non-local return.
Discussion on inline local return and non-local return
Let’s start with the following example, which defines higher-order functions as inline functions:
//Kotlin
inline fun nonLocalReturn(block: ()->Unit){
block()
}
fun main() {
println("Starting")
nonLocalReturn { return }
println("Ending")
}
Copy the code
The console will print:
Starting
We see a non-local return, a global return.
Then let’s look at the following example, if higher-order functions are defined as non-inline functions:
A non-local return cannot be executed from this location
Why does this happen?
For the first example, because it is an inline function, the inline function does not push or push the code directly into the call, so the return is called inside main, so a non-local retuan global return is generated.
crossinline
noinline
Noline: disables inline functions
Inline attribute
Getters and setters for properties without a back-field can be inline by adding inline to the getters and setters
Class MainActivity2: appactivity () {val TAG = "CDX" var pocket: Double = 0.0 // inline var money: Double inline get() = pocket inline set(value) { pocket = value } override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState) setContentView(r.layout.activity_main2) money = 5.0}}Copy the code
And then let’s compile
Found that the money property is no longer available, the money property has been replaced.
6.3. Several useful higher-order functions
Let, run
Let: When we need to define a variable in a particular scope, let is a good choice.
Var person = person (" person ", 25) val name = person.let {it.name} log.e (TAG, name.tostring ())Copy the code
Run: is similar to let except that one is it and the other is this
Var result = person.run {this.age} log.e (TAG, result.tostring ())Copy the code
Also, the apply
Var person = person (" person ", Var person2 = person.also {it. Name = it. Name + "V2"} log. e(TAG, person2.toString()) var person3 = person.apply { name = "xxx" } Log.e(TAG, person3.toString())Copy the code
6.4 set Transformation and sequence
The filter operation
Filter out the ones that fit and put them in the set
Val result = list.filter {it % 2 == 0} log. e(TAG, result.toString()) // [2, 4]Copy the code
The map operation
Iterate through the array, do the operation, and then put it into the collection
val list = intArrayOf(1, 2, 3, 4)
val result = list.map { it * 2 }
Log.e(TAG, result.joinToString())
Copy the code
FlatMap operation
Flow chart of flatMap operation
1) First pull out the elements
2) Then generate an array from the elements
3) Then concatenate these arrays.
List. Fold (StringBuilder()) {acc, I -> log.e (TAG, int, int, int, int, int); "acc=$acc") Log.e(TAG, i.toString()) acc.append(i) }Copy the code
Lazy sequence where is lazy?
By calling asSequence() and then only by calling forEach methods (fold, Ruduce, sum),
The filter, map, and flatMap methods above are executed
6.5. SAM (Single Abstract Method Transformation) transformation
SAM transformation example
If the anonymous inner class has only one method inside it, then the anonymous inner class can be very simplified, with only one {}.
// SAM example var exe: ExecutorService? = null // anonymous inner class // exe? .submit(object: Runnable {// override fun run() {// log.e (TAG," task executed ") //} //}) Submit ({/ / Log. E (TAG, "task") / /}) / / continue to simplify exe? .submit {log. e(TAG, "task executed ")}Copy the code
Kotlin’s anonymous inner class
// The common way to write an anonymous inner class is object: Runnable {override fun run() {log.e (TAG," task executed ")}}Copy the code