Learning notes from java to kotlin

Keywords: Java Attribute Android REST

Preface

In the past, most of android development used java, but because of the introduction of kotlin, the company began to use kotlin, so here is a note to learn kotlin.

Basic grammar

Basic types

There is no basic type in kotlin, where everything is an object, which also leads to its lack of automatic conversion function, such as folat will not automatically up to double, and conversion between basic types in java needs to call the method. Although keywords are used more in this article, it is also an object, but the author follows the java saying.

val i :Int = 7
val d :Double = i.toDouble()//Conversion Method in Int Object
val s = "eeeee"//String type s
val c = s[0]//The string type of kotlin can also be byte-accessed like an array, and can be iterated as an array

Define packages and import packages

This is the same as when using java

package com.lewis.test

import com.lewis.test.util

Defined function

Functions in kotlin are defined with fun as the keyword, and return values are used after function parameter declaration":" Colon is used to define the return value type, of course, it can also automatically determine the return type, and return parameters are also used to return returns.

fun sum(a :Int,b:Int) : Int{
return a+b
}
fun sum(a:Int,b:Int) = a + b//Automatically infer the type of (a+b) returned

fun sum(a:Int,b:Int) = { a + b}//The type returned here is a+b, such as Int

There is no return value in kt (returning meaningless value), that is, void in java. It uses the keyword Unit, which can be omitted generally. The return value of these two functions is Unit (no return value).

 fun test(){
println("555")
}
fun test() :Unit{
println("555")
}

kotlin's functions can use parameter defaults, which java does not support, similar to the default parameters in C++, but somewhat different.

fun defultTest(name :String ,age:Int,sex : String = "Man"){//The third parameter here has the default value Man
    print(name+sex+age)
}
defultTest("lewis",23)//The third parameter can be omitted, which defaults to Man, equivalent to defultTest("lewis",23,"Man").
defultTest("lewis",23,"women")//Instead of using default parameters, use the women value

Here is a small extension. The default parameters in C++ must be placed at the back of the list of function parameters. Otherwise, there will be errors. But kotlin can not make errors when it is used in this way. Personally, I think it is of little significance to put default parameters in the middle.

fun defultTest(name :String ,sex : String = "Man",age:Int){}
//In this case, because the third parameter has no default value, it must pass the third value, so this also leads to the second value must pass, so here, I think that in the actual development to avoid such a design as far as possible.

Variable length parameters

In java, you can use... To indicate that the length of the parameter passed in by the function is not fixed, and kotlin also has this function, but it is not... It's the vararg keyword

fun argTest(vararg data:String){
println(data.size)
    println(data.toList())//Convert to list and call toString() output, which directly outputs data as an array object
}

Local function

There are local functions in kotlin, which, by name, are functions in functions.

fun save(str:String){
fun isEmpty(str:String){//Define an internal function
if (str == null){ throw NullpointException("null")}
}
isEmpty(str)//Call directly within a function, but not externally
}

Local parameter definition

val can only be assigned once, similar to the final of java; var defines variable types, similar to common variables defined by java; the difference between the basic types of two definitions is that the parameters of val can not be assigned again after setting, while var can.

fun main(args : Array<String>){
val a:Int = 1
val b = 2//Automatic recognition of type b as int
val c: Int//Define c, its type is int, the type at this time can not be omitted
c = 3
}
fun main(args:Array<String>){
var d = 5//Automatic recognition of d as int
d += 1//Operators are used in the same way as java
}

Where as keyword classes can be used to convert types, parent-child classes, or mandatory conversions

var a:Int = 3 as Any as Int//This is where 3 is converted to Any and Int (as an example, it doesn't make any sense)

String template

kt can use "",""refer to parameters in strings or"", "refer to parameters in strings or convert the result of"{xxx}"XXXX into strings.

fun stringTest(){
    var a = 5
    val str = "a is $a"//At this point, str's string assignment is"a is 5"
    a = 1
    println(str.replace("is","was")+",but now is $a")
    println("${str.replace("is","was")},but now is $a")
}

if condition judgment

If in kt is similar to that in java. It can be said that kt can be used as java, but kt has more uses, such as if in kt can be used as a return value. In the last sentence of if block, if it is a value, then it is the return value of if. It is important to note that if it needs a return value, the last line of every if conditional block needs to be of the same type. The value of the

fun ifTest(): Int {
    var result =  if (3 == 4) 3 else 4
    return result
}

fun ifTest2():Int{
return if(3==4)println(3)else 4//this lookifThere is no return value.,And the compiler will report errors
}

null nullable value

In kt, if a value can be null, add?, after the type that needs to be declared again, to indicate that the application can be null;
When this parameter is used, it can be invoked only when it is not empty and not when it is empty.
Use!! to ensure that calls are not made when they are not empty, and to throw exceptions for space-time.
Use?: To give it a default value in space-time

var a : Int? = null
var a: Int = null//Errors will be reported here
fun getInt():Int?{//Here the return can be null
...
var a:String? = null
a?.length()//This is called only if a is not empty.
a!!.length()//Where a is empty, an exception is thrown directly.
a?.length() ?:0//Here, when a is empty, use the default value of 0
a.length()//It can't be compiled here, because a may be empty here.
a as? String//This is where a is converted to String type when a is not empty, or null is returned.
}

Type Detection and Automatic Type Conversion

kt uses is keyword to detect the type, and the detected branch can be used directly when the type is used

fun getStringLength(obj:Any):Int?{//Any is any type, similar to java's object
if (obj is String){
return obj.length//In this branch, the obj type is String
}
//Branch obj or String
return null
}

for cycle

kt in keyword is used to iterate through

fun forTest(args:Array<String>){
for(item in args){//Traversing through elements in its array
println(item)//You can't delete here, otherwise you will throw an exception.
}
for(index in args.indices){//Traversing subscripts in its array
println(args[index])//You can't do deletion here either. The size of deleted arrays will be smaller, and at the end, there will be an array crossing. Therefore, if deleted elements, corresponding protective measures should be taken.
}
}

Section

In kotlin,... is used to represent intervals

if(x in 1..3){//Is x in?1reach3Between,Include1and3,If so!inFor if not1reach3Interval
...
}

Iteration interval

for(x in 1..5){//Including 1 and 5
println(x)//1 2 3 4 5
}
for(x in 1..5 step 2){//Including 1 and 5,step 2 indicates that the step size of each iteration is 2.
println(x)//1 3 5
}
for(x in 1 util 5){//1-5, excluding 5, is generally used to traverse lists
println(x)//1 2 3 4
}
for(x in 100 downTo 1 step 3){//downTo is decreasing. Here it is decreasing from 100 to 1. Step size is 3, which is minus 3 each time, including 1 and 100.
println(x)//100 97 94 91...
}

while Loop

This is used in the same way as java

when expression

Similar to java's swich, and when has a return value as well as if, and the use of the return value is the same as if.

fun whenTest(obj : Any) :String =
when(obj){
1 ->"111"
2,3->"2,3"//Multiple cases can be separated by commas
4..7->"4-7"//Use intervals can also be used
"asd" ->"aaaa"
is Long -> "long"
!is String -> "Not string"
else -> "unKnown"
}

Of course, when parameters can not be passed, and when parameters can not be passed, the branching conditions need to be Boolean values.

when{
true->"true"
a ==0 || b == 0->"false"
else "null"
}

abnormal

kotlin's exception is similar to java's and uses try-catch-finally, but it is an expression like if

var result = try{//It returns 22 when there are no exceptions, null when there are exceptions, and it will print change.
Integer.parseInt("22")
} catch(e : NumberFormatException){
null
}finally{
println("change")
}

== Equivalent comparison

In kotlin, == is compared using equals() and is equal in value, while in java, if you use=== for an object, it is equal in reference.
In kotlin, if you need to compare the references to be equal, you need to use the===, third-class sign

class

Definition class

class MainActivity{
}
class MainActivity2(name:String,surname:String)//There are no operations in the class here, so you can ignore the braces, and (name: String, surname String) is the constructor that declares it.
class MainActivity3(var name:String,var surname:String)//This is similar to the previous one, but there is no declaration of attributes in the previous class, but this declares the name and surname parameters.
class MainActivity4(var name:String,var surname:String){
init{
...//This method block is a function body of the main constructor.
}
}

attribute

The constructor declares attributes or attributes declared in the class, and defaults to setter and getter methods. Although in use it is like manipulating attributes directly, it actually calls the corresponding get and set methods. Of course, it can also modify the default set and get methods.

class Test(){
var change0 = 0
var change1 = 1
 get() {
                    return field+1//field is the reserved value, pointing to the parameter obtained, and here it is pointing to change1.
            }
            set(value) {this.change = 2}
//Here, the default methods of get and set for change1 are modified, without affecting change0 and change2.
var change = 2
var change3 = 4
private set//You can set access rights to this class or other
}

Construction method

class Test1(var name:String){//The bracketed name here is such a master constructor that, when there is a master constructor, there can be no slave constructor.
}
class Test2{//No principal constructor
constructor(name:String){//From constructor
this(name,0)//Like java, you can use this to call other constructors
}
constructor(name:String,age:Int){}
}

Generally speaking, we use the main constructor to achieve this, and then other parameters provide the corresponding default values to achieve similar overload functions.

Class inheritance

Classes in kotlin can only inherit classes declared open or abstract, where open is overridden and abstract is abstract

open class Test1(name: String)
abstract class Test2(surname: String)

Declarations to the above two classes can be inherited, using ":" to inherit, not the extends keyword in java

class Test3(name: String) : Test1(name){//Here, the parent class is called by default in the buildTest1(name:String)Construction method
}

kotlin's method is final by default and cannot be overridden, so if it can be overridden, it needs to show the name open or set it to abstract abstract method. After inheritance, override keyword must be override keyword, and override keyword is open by default. So after override, if you want this method not to be overridden, you need to show the final. kotlin's final is similar to java's.

abstract class abTest{
abstract fun one()//Subclasses must be overridden
open fun two(){}//Subclasses can be overridden or not
fun three(){}//Subclasses cannot be overridden
}

Interface

The implementations of interfaces, like inheritance, are all implemented by ":". The methods in interfaces are all open by default, and abstract by default without implementations.
kotlin's interface definition also uses the interface keyword and supports default implementations in the interface
If there is no default method, its subclasses must implement this method. If there is default implementation, subclasses can not be implemented. The default interface is implemented.

interface Clickable{
fun click()
fun showOff() = println("default")//This method has a default implementation
}
interface Clickable2{
fun showOff() = println("default2")//This method has a default implementation
}
class Button : Clickable,Clickable2{
override fun click() = println("click")//Override is an editor that overrides the parent class. It's a comment in java and it's optional, but in kotlin, override is necessary if it's overridden. 
override fun showOff() {//When both interfaces are implemented with the same method, the subclass must override it, otherwise it will report an error.
super<Clickable>.showOff()//Call the implementation of the specified parent class
super<Clickable2>.showOff()
 println("Button")
}
}

Here we can see the difference between inheritance and implementation, inheritance needs to add its construction method, but implementation does not need to.
In addition to methods, kotlin's interface also supports default properties, and kotlin's interface does not store attribute values, only its subclasses will store them.

interface ITest{
val name :String//The name here cannot be assigned, and the attribute must be overridden after the subclass is implemented
val age:Int//get is provided here, and its subclasses do not override age
get() = 1
}
class Test4(override val name :String) :ITest

visibility modifiers

In kotlin, there are public/internal/protected/private, four kinds, which are public by default, while in java, which is different from kotlin, and kotlin has no package private modifier.

Modifier | | class member | | top-level reputation
Public (default) | | | visible everywhere | | visible everywhere
internal | | visible in modules | | visible in modules
protected | | subclass visible | | no use for this
private | | visible in class | | visible in file

Data data class

A data class is provided in kotlin. The data class provides rewriting of equals/hashcode/toString method. It also provides copying method to copy data class. The keyword of the name is data.

data class TestData(val name:String,var age:Int)

enum enumeration class

enum class EnumTest(val a:Int,val b:String ){
    ONE(1,"1"),TWO(2,"2");//Here we define the value of the enumerated class,To define a method,Use it";"Separate,Here is kotlin The only one to use";"Place
    fun printAll() = println("$a,$b")
}

spread function

This is great. You can extend a class method in a place other than a class, or add a function to a class, and then call this method directly when you use it elsewhere, such as adding a Toast method to Context.
It should be noted that the extension function cannot use the protected and private ly modified attributes or methods of the extended class.

//Test.kt
fun Context.toast(message :CharSequence){
    Toast.makeText(this,message,Toast.LENGTH_SHORT).show()
}

//MainACtivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        toast("nfh")//Because Activity inherits Context, the extended function toast in Context can be called directly.
    }
}

Of course, besides adding functions, you can also add attributes.

public var Context.age: Int//Add an attribute age to Context so that all the subclasses of Context and themselves have this attribute
    get() = age
    set(value) { age = value}

It should be noted that the extension function cannot be overridden by subclasses, because the extension function is treated as a static type, and when the extension function name is the same as the member function name, the member function name is preferred.

Internal classes (nested classes)

Internal classes in java, if not named static, hold references to external classes, while static classes do not.
In kotlin, by default, it is not held (equivalent to static), and if you need to hold external class references, you need to use the inner keyword.

class Outer{
inner class Inner{
fun getOut() : Outer = this@Outer//To use external classes, use this @ to reference
}
}

Sealing class

Keyword sealed, a class with sealed name, defaults to open, and its subclasses can only inherit in this class but not outside the class (in Kotlin version 1.1 instead of in the file)

sealed class Expr{
calss Num():Expr()
class Sum():Expr()
}

After kotlin Foundation

Association

A feature of the process is lightweight:
A coroutine is similar to a thread, but it is lighter than a thread. For example, it opens 1000 threads and 1000 coroutines to perform a job. The opening thread is 1000 threads. This is a very resource-consuming place, while 1000 coroutines only open several or dozens of threads to work.

Use of the Concorde

Some packages need to be imported to use the coroutines

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutinesVersion"//The version is used.0.20It's not too much of a problem to get a higher version and a lower version.
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutinesVersion"//This is the package that android uses, and here's an additional way to use handle to schedule the threads that the consortium works on

kotlin's protocol can be turned on using async or launch. Both functions are similar, except that async defaults to asynchronous, i.e. it will not run immediately, and the return values of both are different. Launch returns a Job object, async returns a Deferred(- a lightweight, non-blocking future), and Deferred inherits Job internally, so the difference between the two is not very big.
When using a coroutine, you need to specify the context or environment (or which thread) that the coroutine will execute, and version 0.20 provides the following default environment

//It has a thread pool in it to process your code blocks.
        CommonPool
//Unlimited is what thread is currently.
       Unconfined
//android developer uses android handler to process your code block. The construction method needs to provide handler.
        HandlerContext

Formal use of the protocol

val fu = async(CommonPool  ){

}
println(fu.isCancelled)//Whether the fu protocol is cancelled

val obj = launch(Unconfined){

}
obj.cancel()//Cancel the obj protocol

val UI = HandlerContext(Handler(Looper.getMainLooper()), "UI")
launch(UI){//This is where the UI thread runs.
}

Collection class

The collection classes used in kotlin are java's collection classes. Nevertheless, kotlin adds many methods/functions to it that are easy for developers to manipulate.

val list = arrayListOf(1,4,6,46)//The list here is actually java's Array List
val map = hashMapOf(1 to "one",4 to "four")//The map here is the HashMap of java

Infix call

This is a bit like the feeling of overloading operators in C++, although there is a big gap in appearance.
Like to in a map in a set class, this is a suffix call. The key to define a suffix call function is infix. It can be used in ordinary functions (which need another class, but not top-level functions) and extended functions, and specifies that only one function parameter can be used, and the return value can be dispensed with.

infix fun Int.infixTest(other:Int):Int {//An extension function is defined here, and it supports infix calls.
    println(this+other)
    return this+other
}

c infixTest 3//The infix call returns the sum of c+3
c.infixTest(3)//Of course, this is also possible, the effect is the same.

kotlin provides an extension function to Any, which is implemented as

infix fun Any.to(other:Any) = Pair(this,other)//Pair is a class in the kotlin standard library. It stores a key-value pair, which is actually two elements. So when map is initialized, you can use to define each key-value pair.

String manipulation

kotlin's string processing also uses java's string processing, but kotlin also adds many easy-to-use extension functions to it, such as the function to get the first or last character of the string.

"12.654-A".split(".-".toRegex)//String delimitation, where Regex type is used to solve some character problems
"12.654-A".split(".","-")//kotlin supports multiple character cutting
"""/\.asd\'"""//Triple colons are """on both sides. Strings surrounded by triple colons are pure strings without any escape sequence.

Class delegate

kotlin provides the operation of class delegation with the keyword by, which delegates the implementation part to an attribute when implementing an interface, making this class a transit class.

class ListTest<T> (val list : List<T> = ArrayList()) : List<T> by list{ThereListTestClass implementsList,The implementation part is entrusted to list attribute
override fun add(value : T){//Rewrite add method
println(value)
list.add(value)
}
}

Single case

It's very convenient to implement singletons in kotlin, which can be achieved by using object keyword.

object Test5{//Definition
val data = "data"
fun printAll(){
println(data)
}
}
Test5.printAll()//Invoke singleton

Companion Object

The companion object is a bit like the static method of java, but there is no static in kotlin. Instead, it uses the top-level function, but the top-level function can not access the private member of the class, so it needs the companion object. The key word is companion, which is usually used with object.
And the concomitant object also supports the extension function. Generally, it can be named as an empty concomitant object, which can be extended later.

class A{
companion object{//Define associated objects
fun bar(){
println("associated")
}
}
}
A.bar()//When invoked, it can be invoked directly by type name
interface ITest{
}
class B{
companion object My : ITest{//Define the concomitant object and give it the name My, and implement the interface
fun bar(){
println("associated")
}
}
}
B.My.bar()//Called by class name plus concomitant name
fun ITestTest(test:ITest){//This function needs to be passed in an ITest
}
ITestTest(B)//Or B.My

let function

The let function is somewhat like groovy's closure. After using the let, the caller can be used in {} by it or by customizing other parameters.

var str :String? = "666"
str?.let{//If str is not empty, the content in the let will be invoked, or not.
println(it.length)//The it used at this point is actually the str object
it.indexOf(1)
}

Latinit property delayed initialization

Latinit can be used to name an attribute that is not empty, and the name is not initialized, then initialized, where the attribute needs to be var, if it is val, it must be initialized in the constructor.

private lateinit var data:String

fun setData(s:String){
data = s
}

If data is called before initialization, an error will be reported.

by lazy lazy initialization

Unlike latinit above, by lazy() is initialized when used, and defaults to thread safety.

class User(val name:String){
var age by lazy{
loadAge()//Here is the initialization operation
}
}
var user =User("lewis_v")
user.age//Age initialization occurs only when an age is invoked here

Nothing type

Nothing type is the return value of a function, indicating that the function will not end properly, and that the function will not return anything.

fun fail(msg:String) : Nothing{
throw IllegalStateException(msg)
}
fun fail(msg:String) : Nothing{
return 0//Errors are reported here, and no compilation is allowed. Errors must be made before they can be compiled.
}

Operator overloading

kotlin's operator overloading is similar to C++. Its key word is operator, which can overload binary, unary, compound and comparison operators.

Binary

Binary operations with */%+.
The corresponding overloading method is
Expression | | function name
* || times
/ || div
% || mod
+ || plus
- || minus

data class User(var age:Int){
operator fun plus(other:User):User{//The overload + sign, the left side of the + sign is itself, and the right side is itself.other,Other symbols operate like this
return Point(age + other.age)
}
}
User(5) + User(5) //The result here isUser(10)

Reunite with

Composite has += - = *= /=%.=
Its overloading method is similar to that of its binary operator. On the basis of it, add Assign, such as + plus Assign, minus Assign.

data class User(var age:Int){
operator fun plusAssign(other:User):User{//Overload += sign, += sign on the left is itself, and on the right is itself.other,Other symbols operate like this
return Point(age + other.age)
}
}
var user = User(5)
user += User(5) //The result user here becomesUser(10)

One yuan

Monadic has ++-+!
The corresponding overloading method is
Expression | | function name
+a || unaryPlus
-a || unaryMinus
!a || not
++a,a++ || inc
–a,a– || dec

data class User(var age:Int){
operator fun inc():User{//Overload + + number, unary has no parameter to pass in, only operate on oneself, other symbols operate like this
return Point(age + 1)
}
}
var user = User(5)
user ++  //The result user here becomesUser(6)

Comparison operator

== Rewrite equals
Comparable is needed for the rest of the comparisons, such as ><>=<==, where the method compareTo is implemented, and when compared, the value returned by this method is compared.

Summary

These are the learning notes of kotlin. Generally speaking, kotlin is more convenient and concise to use, and it has provided many common operations such as the operation of collection classes and so on.

Posted by peri on Sat, 11 May 2019 22:54:48 -0700