Kotlin 集合循环及对象


前面讲了For循环,遍历时,语法如下 : for (i in collection) { print(i) } ,这是一个代码块,具体的比如说

    val ints = arrayOf(1, 4, 5)
    for (i : Int in ints) {
        // ……
    }

在这个地方, ints 是数字类型的数组,for 循环中可以写明白它的类型;上面的写法,和下面的效果一样

    for (i : Int in ints.iterator()) {
        // ……
    }

对于数组使用 arrayOf(),对于普通集合可以使用 listOf() 和 setOf() ,如果想使用 ArrayList、HashSet、 HashMap 等则使用 arrayListOf()、hashSetOf()、hashMapOf(Pair(K,V));对于 List 集合而言,它有个属性 array.indices ,这个可以说是它的索引,通过遍历它来获取索引对应的值

    val ints = arrayOf(1, 4, 5)
    for (index   in  ints.indices) {
        println(ints[index])
    }

这样就打印出了值 。或者使用 array.withIndex() 方法,这个是同时获取索引 index 和值 value,可以看看它的写法

    val ints = arrayOf(1, 4, 5)
    for ((index, value)   in  ints.withIndex()) {
        println("index is  $index and value is $value")
    }

打印出的结果是

index is  0 and value is 1
index is  1 and value is 4
index is  2 and value is 5

对于 while 循环和 do...while() 循环,用法和Java中一样,这里就不多说了。关于for循环中的 continue 和 break 和 return,用法和Java中控功能也一样。

    for (i in 1..9) {
        if (i == 2) {
            continue
        }
        println(i)
        if (i == 6) {
            break
        }
    }
    println(" end ")

打印结果是

1
3
4
5
6
 end

如果把里面的 break 换成 return,试试

    for (i in 1..9) {
        if (i == 2) {
            continue
        }
        println(i)
        if (i == 6) {
            return
        }
    }
    println(" end ")

打印结果是

1
3
4
5
6

由此可以看出,用法和java中的一样:continue 是 跳过本次继续;break 是跳出当前 for 循环,继续;return 是 跳出当前for循环,同时到此为止,不会继续往下执行。数组和 list 有个 forEach 的方法,我们再写写看

    val ints = arrayOf("a", "b", "c")
    ints.forEach {
        println(it)
    }

it在此时指的就是数组中的元素对象,打印结果为

a
b
c

Kotlin 中的对象,也是以 class 开头的,比如说

class A{

}

class A

在这里,创建一个A的对象的话是 val a = A() ,由于 A 是个空对象,里面没有任何属性和方法,所以也可以简化,去掉大括号,实际操作中不可能写这个一个不用的空类,这里只是举个例子。如果类中要添加属性,可以使用 val 或 var 来修饰,如下

class Student() {
    var age = "Tom"
    var addre = "BJ"

    override fun toString(): String {
        return "$age  $addre"
    }
}

如果要重写父类的方法,这里使用 override 来标记,其他地方和我们自己定义方法的写法一样,这里创建对象也是 val b = Student(), kotlin 中创建对象可以不使用 new 关键字,如果我们想添加多个构造方法怎么办?

class Student1(age: String, address: String) {
    var age = age
    var addre = address

    constructor() : this("Tom", "BJ")
    constructor(age: String) : this(age, "BJ")

    override fun toString(): String {
        return "$age  $addre"
    }
}

Kotlin 中的多个构造方法写法与 Java 中的不一样,它里面是以 constructor 来表示构造方法,括号里面跟随参数,然后使用冒号来表示引用一个其他的构造方法,但最终要引用到 class 后面定义的主构造方法,我们来创建几个对象,然后打印一下,看看数据

    val a = Student1()
    val b = Student1("Jack")
    val c = Student1("Jack", "SH")
    val list = listOf(a, b, c)
    for (i in list){
        println(i)
    }
    println("b.addre  is  ${ b.addre}" )

上面是创建了三个对象,然后添加到list集合中,接着遍历打印它的值

Tom  BJ
Jack  BJ
Jack  SH
b.addre  is  BJ

我们重写了 toString() 方法,因此打印的就是我们定义的值;获取对象中的属性值,kotlin中不需要自定义 set 和 get 方法,直接像上面写法直接调用即可。

如果我们想在set和get时对属性值进行修改,但 kotlin 中没有这两个方法,怎么办?不用急,仍然是举个例子

class Teacher(){
    var name : String = "Father"
    get() = field.toUpperCase() // 注意此处是 field,不是直接使用 name 属性
    set

    var age : Int = 20
    get() = field
    set(value) {
        if (value in 20..60) {
            field = value  // 注意此处是 field,不是直接使用 age 属性
        } else {
            field = -1
        }
    }

}

这个例子中,对象有两个属性 name 和 age,我们在这两个属性下main可以重写 set 和 get 方法,并进行简单的逻辑判断,这里要注意一点,例子中赋值和取值时使用的都是 field 这个关键字,而不是属性名字本身,因为在此处 field 代表的就是属性本身。在 kotlin 中,属性会被编译自动添加 get 和 set 方法,如果 我们这么写了

    var age : Int = 20
        get() = age
        set(value) {
            if (value in 20..60) {       // 如果传入的值小于 10 返回该值
                age = value
            } else {
                age = -1         // 如果传入的值大于等于 10 返回 -1
            }
        }

翻译成 java 代码,意思就是

    int age = 20;
    public int getAge() {
        return getAge();
    }
    public void setAge(int age) {
        if(age >= 20 && age <= 60){
            setAge(age);
        } else {
            setAge(-1);
        }
    }

这样,很容易就是死循环了,不停的调用本身,所以切记,在 kotlin 中对属性使用 set 和 get 修饰时,一定要使用 field 关键字。


对于类中的代码块,kotlin 中是使用 init 来表示,静态代码块也是用 init 来表示,不过需要写在 ompanion object 修饰的大括号里;对于静态常量也是写在在这地方,例子

class Customer(val name: String = "make"){

    var nol: String  = "abc"
    companion object{
        val cus = "abcdef"
        const val cus1 = "ab"
        init {
            println(" this is static Customer ")
        }
    }

    init {
        println(" this is Customer ")
    }

    override fun toString(): String {
        return name
    }
}

fun test(){
    val customer = Customer()
    val customer1 = Customer()
    println(customer.nol)
    println(Customer.cus)
    println(Customer.cus1)
}

打印结果是 

 this is static Customer 
 this is Customer 
 this is Customer 
abc
abcdef
ab

这里也可以印证,如果我们直接用类引用 nol 是会失败的; const 是关键字,静态默认都是 private 的,如果在其他的 Java 类中引用静态变量,是会失败的,如果添加了 const ,则把它变为 public 类型,Java 中的其他类就可以引用了。


Java 中,class 类和方法默认都是非 final 的,只要不是 private 修饰,class 类是可以被继承,方法是可以被重写的,但在 Kotlin 中,类和方法默认都是 final 类型的,如果想继承类或重写方法,都需要用 open 这个关键字修饰。在 kotlin 中,所有的类的基类是 Any,我们看看它的写法

public open class Any {

    public open operator fun equals(other: Any?): Boolean

    public open fun hashCode(): Int

    public open fun toString(): String
}

class 类 和方法前面都有 open 修饰,我们定义类的话也可以仿照它来写

open class B {
    public open fun b() : Unit{

    }
}

open class C : B(){
    override fun b() {
        super.b()
    }
}

对于抽象类和接口,也是如此。注意一点,kotlin 中的接口中,可以定义方法实现,举例

interface IA{
    fun prin(){
        println("this is IA prin")
    }

    fun prin1()
}

class IAImpl : IA{

    override fun prin() {
        println("this is IAImpl prin")
    }

    override fun prin1() {
        println("this is IAImpl prin1")
    }

}

fun test1(){
    var ia : IA = IAImpl()
    ia.prin()
    ia.prin1()
}

打印结果为

this is IAImpl prin
this is IAImpl prin1
发布了176 篇原创文章 · 获赞 11 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Deaht_Huimie/article/details/103363342