kotlin在处理数字时与java类似,但又不完全相同.
例如在数字没有隐式拓展;
有些情况下的字面值有所不同;
在kotlin中字符不是数字;
Double64
Float 32Long64
Int 32Short16Byte8
十进制: 123Long类型:123L
十六进制:0x01
二进制:0b11011000
不支持八进制
Double:123.5
Float:123.5f
可以使用下划线增加数组的可读性
val oneMillion=1_000_000
在 Java 平台数字是物理存储为 JVM 的原生类型,除非我们需要一个可空的引用(如
Int? )或泛型。 后者情况下会把数字装箱。
fun box(v:View){
val a:Int =10000
Log.d("meee",""+(a === a));
val b:Int?=a;
val c:Int?=a;
Log.d("meee",""+(b === c));//注意,装箱后不保证同一性,这里为false//但会保持数字的相等
Log.d("meee",""+(b == c));//true//假设代码,实际上不能被编译//Long 和Int即使值相等也不能陪判断为==val ten:Int? =10;
val tenL:Long?=ten;
Log.d("meee",""+(a==b));//false//所以同一性还有相等性都会在所有地方悄无声息地失去
}
显式转换
toByte(): BytetoShort(): ShorttoInt(): InttoLong(): LongtoFloat(): FloattoDouble(): DoubletoChar(): Char val byte:Byte=1/* //不能通过编译
val int:Int=byte*///显式转换
val int:Int=byte.toInt()
相等性检测: a == b 与 a != b
比较操作符: a < b 、 a > b 、 a <= b 、 a >= b
区间实例以及区间检测: a..b 、 x in a..b 、 x !in a..b
fun calculate(v:View){
val num=0b1101_1000
Log.d("meee",""+num);//216
val num2=num shl 1
Log.d("meee",""+num2);//432
Log.d("meee",""+(0.9 in 1..10));
}
字符
字符用 Char 类型表示。它们不能直接当作数字
fun myChar(v:View){
val char:Char='a'
Log.d("meee","char:"+char);//a
/* //编译错误,类型不同不能判断
Log.d("meee",""+(char == 97));*/
//可以对char进行显式转换
Log.d("meee",""+(char.toInt() == 97));//true
}
数组在 Kotlin 中使用 Array 类来表示,它定义了 get 和 set 函数(按照运算符重载约定
这会转变为 [] )和 size 属性,以及一些其他有用的成员函数:
classArray<T> privateconstructor(){
val size: Int
operator fun get(index: Int): T
operator fun set(index: Int, value: T): Unit
operator fun iterator(): Iterator<T>
// ……
}
fun myArray(v:View){
//创建方式一
val numArray= arrayOf(1,2,3)
Log.d("meee",""+numArray[0]);//1,[]代表数组的get set
Log.d("meee",""+numArray[1]);//2
Log.d("meee",""+numArray[2]);//3//创建一个大小为3空数组
var nullArray= arrayOfNulls<String>(3)
//创建方式二
val asc=Array(5,{i -> (i*i).toString()})//i为0 1 2 3 4
Log.d("meee",""+asc[0]);
Log.d("meee",""+asc[1]);
Log.d("meee",""+asc[2]);
Log.d("meee",""+asc[3]);
Log.d("meee",""+asc[4]);
/*与 Java 不同的是,Kotlin 中数组是不型变的(invariant)。这意味着 Kotlin 不让我们把
*Array<String> 赋值给 Array<Any> ,以防止可能的运行时失败*/
}
fun testIf(v:View){
val a=1;
val b=2if(a<b){
Log.d("meee","a<b");
}
if (b<a){
}else{
Log.d("meee","b>a");
}
//在kotlin中 if 是一个表达式,即它会返回一个值//如果为代码块,则最后为该块的值//if 作为表达该表达式需要有 else 分支。varmin=if (a<b) {
Log.d("meee","= =")
a
} else {11.1}
Log.d("meee","min:"+min);//1
}
When
类似switch,
也可以作为表达,同样必须要有else分支
when (x) {
1 ->print("x == 1")
2 ->print("x == 2")
else -> { // 注意这个块
print("x is neither 1 nor 2")
}
}
//如果很多分支需要用相同的方式处理,则可以把多个分支条件放在一起,用逗号分隔:
fun testWhen2(v:View){
varx:Int=3
val str=when(x){
1,3,5 ->"单数"2,4,6 ->"双数"else ->"超出计算能力"
}
Log.d("meee",""+str);
}
//可以使用任意表达式作为分支条件
fun testWhen2(v:View){
varx:Int=3
val str=when(x){
1,3,5 ->"单数"2,4,6 ->"双数"//方法
getTen() ->"哟呵你还能输入个10进来"//区间
in666..999 ->"666"//也可以通过类型判断,并且会自动转化,当然这里是编译不通过的
is String ->"string"else ->"超出计算能力"
}
Log.d("meee",""+str);
}
fun getTen():Int=10;
//when 也可以用来取代 if - elseif 链。 如果不提供参数,所有的分支条件都是简单的布
尔表达式,而当一个分支的条件为真时则执行该分支:
when {
x.isOdd() ->print("x is odd")
x.isEven() ->print("x is even")
else ->print("x is funny")
}
For
for 循环可以对任何提供迭代器(iterator)的对象进行遍历,这相当于像 C# 这样的语言中
的 foreach 循环。语法如下:
for (item in collection) print(item)
循环体可以是一个代码块。
for (item: Int in ints) {
// ……
}
如上所述, for 可以循环遍历任何提供了迭代器的对象。即:
有一个成员函数或者扩展函数 iterator() ,它的返回类型
有一个成员函数或者扩展函数 next() ,并且
有一个成员函数或者扩展函数 hasNext() 返回 Boolean 。
这三个函数都需要标记为 operator 。
//如果你想获取数组或者集合的索引//注意这种“在区间上遍历”会编译成优化的实现而不会创建额外对象。//list
val list= ArrayList<String>()
list.add("你")
list.add("好")
list.add("啊")
for (index in0 until list.size){
Log.d("meee",""+list.get(index));
}
for ((index,value) in list.withIndex()){
Log.d("meee","index is $index,value is $value");
}
//数组
val arr= arrayOf("1","2","3")
for (i in arr.indices){
Log.d("meee",""+arr[i]);
}
for ((index,value)in arr.withIndex()){
Log.d("meee","index is $index,value is $value");
}
While doWhile
同java
返回和跳转
Kotlin 有三种结构化跳转表达式:
return 。默认从最直接包围它的函数或者匿名函数返回。
break 。终止最直接包围它的循环。
continue 。继续下一次最直接包围它的循环。
所有这些表达式都可以用作更大表达式的一部分:
val s = person.name ?: return//返回类型为Nothing
标签的使用
fun testLabel(v:View){
//labelName@创建标签
loop@ for (x in1..100){
if (x%10==0){
//continue@loop跳过这次循环continue@loop
}
if (x==51){
//终止这次循环break@loop
}
Log.d("meee","x:"+x);
}
}
funct@{
//结束方法return@lit
}
//隐式标签,该标签与接受该lambda 的函数同名。
fun foo() {
ints.forEach {
if (it == 0) return@forEachprint(it)
}
}
//普通方法
fun add(a: Int, b: Int): Int {
returna + b
}
//将表达式作为方法的返回值时,会自动判断返回类型
fun add2(a: Int, b: Int) = a + b
局部常量
定义
val a:Int =1//自动推断val b=1//没有初始化则不能自动推断,且只能被赋值一次,未赋值使用编译报错val c:Long
局部变量
var x:Int =1;
全局变量和常量
全局常量和变量与局部变量相同,但是必须在定义时初始化或抽象修饰
Lamdba的使用
button.setOnClickListener(object:View.OnClickListener{
override fun onClick(v: View?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
})
button.setOnClickListener{view->
}
button.setOnClickListener{
}
字符串模版
var a:String="小黄"val saying="你是$a"//saying:你是小黄//{}内是代码val saying2="你是${a.replace("小黄","老江")}"//saying2:你是老江
使用可空值
//返回类型可以为null
fun getNull():Int?{
returnnull
}
public fun test(view:View){
var n=getNull()
//使用可空值时,必须进行非空判断if (n!=null){
var x=n+1
Log.d("meee","x:"+x);
}
//或者空检测if (n==null){
return;
}
}
fun testfor(view:View){
varlist:ArrayList<String>= ArrayList()
val list2= listOf<String>("你好","你好","你好");
list.add("你好啊")
list.add("你好啊")
list.add("你好啊")
list(list)
//不包括100
for (i in0 until 100){
Log.d("meee","哈哈"+i);//输出至哈哈99
}
}
fun list(list:ArrayList<String>){
//类似增强型for循环了
for(item inlist){
Log.d("meee",item);
}
}
When表达式
//类似switch
fun getItemName(index:Int):String{
when(index){
0->return"Zero"1->return"One"2->return"Two"else->return"Null"//类似default
}
}
分号的作用
分割同一行的不同函数
Range
//使用in运算符来检测某个数字是否在指定区间内
fun testRange(view:View){
Log.d("meee","38:"+isIn39to50(38));//falseLog.d("meee","39:"+isIn39to50(39));//trueLog.d("meee","49:"+isIn39to50(49));//trueLog.d("meee","50:"+isIn39to50(50));//trueLog.d("meee","38:"+isNotIn39to50(38));//trueLog.d("meee","39:"+isNotIn39to50(39));//falseLog.d("meee","49:"+isNotIn39to50(49));//falseLog.d("meee","50:"+isNotIn39to50(50));//false
}
fun isIn39to50(num:Int):Boolean{
if (num in39..50){
returntrue;
}
returnfalse;
}
fun isNotIn39to50(num:Int):Boolean{
if (num !in39..50){
returntrue;
}
returnfalse;
}
fun listMap(v:View){
val map=HashMap<Int,String>()
map.put(1,"小黄")
map.put(2,"老江")
map.put(3,"灶杰")
Log.d("meee","map:"+map);
for((k,v) inmap){
Log.d("meee","$k 映射 $v");
}
}
创建只读list map
//创建只读list mapfun readOnlyListAndMap(v:View){
val list= listOf<String>("1","2","3")
val map= mapOf<Int,Int>(1to100,2to300,3to1000)
}
ByLaze
fun ByLazy(v:View){
//第一次被调用时就被初始化,想要被改变只能重新定义,只能在val上使用val str:String by lazy { "你好啊" }
Log.d("meee","str:"+str);
}
拓展函数
fun String.addFun(){
Log.d("meee","= =");
}
fun String.toLowerCase(){
Log.d("meee","= =");
}
fun extendFunction(view:View){
"你好啊".addFun()
//如果存在同名的方法,则默认以覆盖为准
"s".toLowerCase()//Log.d("meee","= =");
}
单例
objectSingleInstance{val name="小黄"
}
fun singleInstance(v:View){
Log.d("meee","SingleInstance.name:"+SingleInstance.name);
Log.d("meee","SingleInstance:"+SingleInstance);
}
非空判断的缩写
//非空判断的缩写
fun notNull(v:View){
var str:String?=null//非空判断执行对象的方法
str?.addFun()//不会执行addFun();//if not null
val str2="12"
str2?.let {
Log.d("meee","str2不为空");
}
//if null
val str3:String?=null
str3?:Log.d("meee","str3为空");
//if not null and else
val obj=str?.length?:"空的"Log.d("meee",""+obj);//"空的"
}
以When表达式为返回值
fun returnWhen(v:View){
Log.d("meee",""+returnWhen("red"));
Log.d("meee",""+returnWhen("blue"));
Log.d("meee",""+returnWhen("unkonw"));
}
fun returnWhen(color:String):String{
return when(color){
"red"-> "红色""green"-> "绿色""blue"-> "蓝色"else-> "找不到该颜色"
}
}
try-cache表达式
fun tryCache(v:View){
var str=try {
throw RuntimeException("呵呵")
"你好啊"
}catch (e: RuntimeException){
}
Log.d("meee",""+(str==null));
}
对同一个对象调用多个方法>>With 关键字的使用
fun MutilMethodCall(v:View){
val tri=Tri()
with(tri){
//在with关键字内可以直接调用该对象的方法for(x in1..5){
add1()
add2()
add3()
}
}
}
class Tri(){
fun add1(){
Log.d("meee","side1");
}
fun add2(){
Log.d("meee","side2");
}
fun add3(){
Log.d("meee","side3");
}
}
FileIo流的使用方法(亲测不行,找不到Files类)
val stream = Files.newInputStream(Paths.get("/some/file.txt"))
stream.buffered().reader().use { reader ->
println(reader.readText())
}
泛型返回值的使用
inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json,
T::class.java)
可空布尔值的使用
fun notBoolean(v:View){
val flag:Boolean?=nullif(flag==true){
Log.d("meee","true");
}else{
Log.d("meee","false or null");
}
}
同步方法
@Synchronized
fun getInstance():APP {
if(app==null){
app=APP()
}
return app as APP
}
静态方法
//companion object表示伴随object,也就是java的静态方法的意思
companion object{
var app: APP? = null
@Synchronized
fun getInstance():APP {
if(app==null){
app=APP()
}
return app as APP
}
}