可怕!从简洁高效的角度来说,Kotlin比Java强太多了吧!难道Java真的要被替代了?

这里分享9个Kotlin比Java高效的tips。以下文章是在使用Kotlin写过几个项目,在对Kotlin有了一些基础后总结出来的,比较适合对于Kotlin有一定基础,有所了解的小伙伴。。

Tip1- 更简洁的字符串

如果要在Java中让字符串嵌套需要转义的字符,那无疑是一件非常非常痛苦的事!比如,当要想表示下面这个字符串时,你的代码可能要写成这样:

public void testString() {
        String js = "function myFunction()\n" +
                "{\n" +
                "    document.getElementById(\"demo\").innerHTML=\"My First JavaScript Function\";\n" +
                "}";
        System.out.println(js);
}

而Kotlin呢?Kotlin引入了三引号”“”,三引号中可以包含反斜杠、换行等特殊字符。

fun testString() {
    val js = """
        function myFunction()
        {
            document.getElementById("demo").innerHTML="My First JavaScript Function";
        }
        """.trimIndent()
    println(js)
}

代码是不是简洁清晰了很多?
同时,Kotlin引入了字符串模板,方便字符串的拼接,可以用$符号拼接变量和表达式。

fun testString() {
    val strings = arrayListOf("abc", "efd", "gfg")
    println("First content is $strings")
    println("First content is ${strings[0]}")
    println("First content is ${if (strings.size > 0) strings[0] else "null"}")
}

Tip2- 更好调用的函数:显式参数名/默认参数值

Kotlin中函数更加好调用,主要表现在两方面:1、显示地表示参数名;2、函数可以有默认参数值这可以大大减少Java中函数的重载

fun saySomething(somethingToSay:String = "hello",
                     isBadMan: Boolean = false,
                     isStranger: Boolean = false,
                     isMyHater: Boolean = false) {
    if(isBadMan) {
        System.out.println("you should work hard day by day")
        return
    } else if(isStranger) {
        System.out.println("nice to meet you")
        return
    } else if(isMyHater) {
        System.out.println("i hate you")
        return
    }
    System.out.println("$somethingToSay")
}
/*
* 测试
* */
fun main() {
    saySomething(isBadMan = true)//输出you should work hard day by day
    saySomething("how are you")//输出how are you
}

如上面的代码,由于Kotlin可以指定参数值,还可以给参数默认值,减少了大量函数的重载。

Tip3- 利用局部函数抽取重复代码

Kotlin中提供了函数的嵌套,在函数内部还可以定义新的函数。这样代码的层次性更强,可读性也更强。

fun validateUser() {
    fun validate(value: String, fildName: String) {
        if (value.isEmpty()) {
            throw IllegalArgumentException("Can't save user $id: empty $fildName")
        }
    }

    validate(name, "Name")
    validate(address, "Address")
    validate(email, "Email")
}

Tip4- 使用数据类来快速实现model类

在java中要声明一个model类需要实现很多的代码,如下所示,

public class User : Serializable {
        private String name;
        private int age;
        private int gender;
        private String address;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public int getGender() {
            return gender;
        }

        public void setGender(int gender) {
            this.gender = gender;
        }

        public String getAddress() {
            return address;
        }

        public void setAddress(String address) {
            this.address = address;
        }
}

这段代码用kotlin,只需要一行代码就可以做到。

class User(val name: String, val age: Int, val gender: Int, var address: String)

Tip5- 用类委托来快速实现代理模式

Java中要想实现装饰器模式:创建一个新类,实现与原始类一样的接口并将原来的类的实例作为一个成员变量。 与原始类拥有相同行为的方法不用修改,只需要直接转发给原始类的实例。如下所示

class CountingSet<T>(val innerSet: MutableCollection<T> = HashSet<T>()) : MutableCollection<T> {

    var objectAdded = 0

    override val size: Int
        get() = innerSet.size

    /*
    * 需要修改的方法
    * */
    override fun add(element: T): Boolean {
        objectAdded++
        return innerSet.add(element)
    }

    /*
    * 需要修改的方法
    * */
    override fun addAll(elements: Collection<T>): Boolean {
        objectAdded += elements.size
        return innerSet.addAll(elements)
    }

    override fun contains(element: T): Boolean {
        return innerSet.contains(element)
    }

    override fun containsAll(elements: Collection<T>): Boolean {
        return innerSet.containsAll(elements)
    }

    override fun isEmpty(): Boolean {
        return innerSet.isEmpty()
    }

    override fun clear() {
        innerSet.clear()
    }

    override fun iterator(): MutableIterator<T> {
        return innerSet.iterator()
    }

    override fun remove(element: T): Boolean {
        return innerSet.remove(element)
    }

    override fun removeAll(elements: Collection<T>): Boolean {
        return innerSet.removeAll(elements)
    }

    override fun retainAll(elements: Collection<T>): Boolean {
        return innerSet.retainAll(elements)
    }

}

如上所示,想要修改HashSet的某些行为函数add和addAll,需要实现MutableCollection接口的所有方法,将这些方法转发给innerSet去具体的实现。虽然只需要修改其中的两个方法,其他代码都是模版代码。 只要是重复的模版代码,Kotlin这种全新的语法糖就会想办法将它放在编译阶段再去生成。 这时候可以用到类委托by关键字,如下所示:

class CountingSet2<T>(val innerSet: MutableCollection<T> = HashSet<T>()) : MutableCollection<T> by innerSet {

    var objectAdded = 0

    override fun add(element: T): Boolean {
        objectAdded++
        return innerSet.add(element)
    }

    override fun addAll(elements: Collection<T>): Boolean {
        objectAdded += elements.size
        return innerSet.addAll(elements)
    }
}

Tip6- apply函数来简化代码

  • apply 函数原型:

    inline fun T.apply(block: T.() -> Unit): T { block(); return this }

  • apply函数,在函数范围内,可以任意调用该对象的任意方法,并返回该对象

    fun testApply(context: Context) {
    var imgView = ImageView(context).apply {
        setBackgroundColor(0)
        setImageBitmap(null)
    }
    
    var textView = TextView(context).apply {
        text = "content"
        textSize = 20.0f
        setPadding(10, 0, 0, 0)
    }
    
    var user = User().apply { 
        age = 15
        name = "Jack"
        val a = address
        address = "bbb"
    }
    }

    通过apply后,在apply的大括号里可以访问类的公有属性和方法。另外,在类实例化的时候,就可以通过apply把需要初始化的步骤全部实现,非常的简洁。

Tip7- 用函数型变量来简化回调

Java中定义一个回调需要写很多冗余代码,包括定义一个接口,一个接口类型的成员变量。。。而Kotlin中变量可以是一个函数,所以定义回调非常简洁直观。

参考

https://github.com/heimashi/kotlin_tips#tip8–%E4%BD%BF%E7%94%A8%E6%95%B0%E6%8D%AE%E7%B1%BB%E6%9D%A5%E5%BF%AB%E9%80%9F%E5%AE%9E%E7%8E%B0model%E7%B1%BB

猜你喜欢

转载自blog.csdn.net/colinandroid/article/details/80490040