Kotlin学习笔记(一)—基础语法与Java全面PK
2018-02-09 15:53
183 查看
前言
Kotlin作为Google承认的新的Android开发语言必定有其可取之处。现在开始,我也要随波逐流,记录学习Kotlin的点点滴滴。同时,通过将Kotlin还原成Java代码,对比两种语言的优劣。当然,当你能将某个Kotlin知识点还原成Java就可以算你掌握了这个知识点。文章大部分通过官方文档学习而来,要想原汁原味的朋友可以点击下面链接:Kotlin官网
1.函数定义
Kotlin定义函数方法有下面几种形式:1.函数带两个参数和返回值:
fun sum(a:Int,b:Int):Int{ return a+b }
对应Java代码:
int sum(int a,int b){ return a+b; }
2.函数通过表达式推断函数返回值:
fun sum(a:Int,b:Int) = a + b
对应Java代码:
int sum(int a,int b){ return a+b; }
3.函数无返回值或者说返回值无意义:
fun sum(a:Int,b:Int):Unit{ println("sum of $a and $b is ${a+b}") }
or
fun sum(a:Int,b:Int){ println("sum of $a and $b is ${a+b}") }
对应Java代码:
void sum(int a,int b){ System.out.println(String.format("sum of %d and %d is %d",a,b,a+b)); }
Tips:在字符串内$符号后带变量名代表这个变量的值,$符号后带{},代表{}里面表达式的值。Unit返回类型相当于Java里的void
4.函数参数含数组参数:
fun printArray(vararg args:Int){ for(arg in args){ print("$arg ") } }
or
fun printArray(args:Array<Int>){ for(arg in args){ print("$arg ") } }
对应Java代码:
void printArray(Integer...args){ for(Integer arg:args){ System.out.println(arg+" "); } }
2.定义常量和变量
1.Kotlin常量相当于Java里对变量添加final,定义时复制后将不能改变其值:val a: Int = 1 // 直接定义时赋值 val b = 2 // 在常量声明时可不指定类型 val c: Int // 定义时不赋值 c = 3 // 在其他地方才赋值
注意:第三种方式定义常量时必须要制定类型,否则编译出错。
对应Java代码
final int a = 1; final int b = 2; final int c = 3;
这里Kotlin和Java的区别就体现出来了,Java声明常量必须要给常量赋初值,必须指定常量的类型。而Kotlin可以不声明常量类型,并且可以延后给常量赋值,但需要声明常量类型。
3.注释
Kotlin的注释跟Java完全一样。4.使用条件表达式
Kotlin使用条件表达式与Java的写法有出入,但效果没明显区别。fun max(a:Int,b:Int):Int{ return if(a>b) a else b }
or
fun max(a:Int,b:Int):=if(a>b) a else b
对应的Java代码
int max(int a,int b){ return a > b ? a : b; }
5.可空的参数或返回值
Kotlin对于可空的参数和返回值,在声明参数类型后加?符号,表示参数可空。fun toInt(s:String):Int?{ return s.toIntOrNull(); }
对应Java代码
@Nullable Integer toInt(String s){ return Integer.valueOf(s); }
注意:在Java代码中Integer.value()方法若参数不可转为整形会crash。
6.检查类型
Kotlin在检查类型写法也与Java不同。Kotlin用is代替了Java的Instanceof。此外,如果变量被检查符合某种类型,无需进行强制转换,系统将自动将变量转换为那个类型。例如:fun getStringLength(obj:Any):Int?{ if(obj is String){ //系统自动将obj转换为String类型 return obj.length } else //return obj.length 在此处使用obj.length将报错 return null }
or
fun getStringLength(obj:Any):Int?{ if(obj !is String){ return null //return obj.length 在此处使用obj.length将报错 } else //系统自动将obj转换为String类型 return obj.length }
对应的Java代码
@Nullable Integer getStringLength(Object obj){ e671 if(obj instanceof String){ String s = (String)obj; return s.length; }else{ return null; } }
7.遍历数组类型
Kotlin在遍历数组上与Java上也有区别,如下:val items = listOf("apple", "banana", "kiwi") for (item in items) { println(item) }
or
val items = listOf("apple", "banana", "kiwi") for (index in items.indices) { println("item at $index is ${items[index]}") }
对应的Java代码
final String[] items = new String[]{"apple","banana","kiwi"}; for(String item:items){ System.out.println(item); }
or
final String[] items = new String[]{"apple","banana","kiwi"}; int size = items.size; for(int i = 0;i<size;i++){ System.out.printlin(String.format("item at %d is %s",i,items[i])); }
8.while循环
Kotlin在用while循环与Java无任何区别。9.范围检查
Kotlin相对于Java简化了数据范围检测的写法。如下:1.检查数据是否在数值范围内
val x = 10 val y = 9 if (x in 1..y+1) { println("fits in range") }
对应Java代码
final x = 10; final y =9; if(x>=1&&x<=y+1){ System.out.println("fits in range"); }
2.检查数据是否在数值范围外
val list = listOf("a", "b", "c") if (-1 !in 0..list.lastIndex) { println("-1 is out of range") } if (list.size !in list.indices) { println("list size is out of valid list indices range too") }
对应Java代码
final Array<String> list = Arrays.asList("a","b","c"); if(-1 < 0||-1 > list.size()-1){ System.out.println("-1 is out of range"); } if(list.size()<0||list.size()>list.size()-1){ System.out.println("list size is out of valid list indices range too"); }
通过上面的对比,Kotlin的代码效率就体现出来了。
3.遍历数值范围
for (x in 1..5) { print(x) }
对应的Java代码
for(int i=0;i<=5;i++){ System.out.print(x+""); }
4.步进遍历数值范围
for (x in 1..10 step 2) { print(x) } println() for (x in 9 downTo 0 step 3) { print(x) }
对应的Java代码
int x; for(x = 1;x<=10;x+=2){ System.out.print(x+""); } System.out.print("\n"); for(x=9;x>=0;x-=3){ System.out.print(x+""); }
通过对比,Kotlin的代码简洁性又体现出来了。
10.when表达式
when表达式是Kotlin新增的用于多情况的取值判定。来见识一下他的威力:fun describe(obj:Any):String = when(obj){ 1 -> "One" "Hello" -> "Greeting" is Long -> "Long" !is String -> "isn't String" else -> "Unknown" }
对应的Java代码:
String describe(Object obj){ if(obj instanceof Integer && (int)obj == 1){ return "One"; }else if(obj instanceof String &&((String)obj).equal("Hello")){ return "Greeting"; }else if(obj instanceof Long){ return "Long"; }else if(!(obj instanceof String)){ return "isn't String"; }else{ return "Unknown"; } }
我已经是尽量简洁的用Java代码还原,但是由于Java代码需要各种判定类型,强制转换,简洁性终究还是被Kotlin完胜。此外,when还能这样操作:
val a = "bbb"; val b = 5; when{ a.equal("bbb") -> { print("a is bbb") print("a") } b == 5 -> print -> print("b == 5") }
两种when的区别是前者是对()内的对象进行判定。后者是不指定对象。
11.集合操作
Kotlin对于集合的操作可谓是对Java代码的又一颠覆。对比一下:1.判断对象是否在集合内
val fruits = setOf("apple","banana","orange") if("apple" in fruits){ println("apple is in fruits") }
而Java代码
final Set fruits = new HashSet(); fruits.add("apple"); fruits.add("banana"); fruits.add("orange"); if(fruits.contains("apple")){ System.out.println("apple is in fruits"); }
2.对集合的一系列操作
val fruits = listOf("banana", "avocado", "apple", "kiwi") fruits .filter { it.startsWith("a") } //过滤非a开头的元素 .sortedBy { it } //对集合排序 .map { it.toUpperCase() } //重新映射 .forEach { println(it) } //逐个操作集合元素
看到这代码是不是似曾相识。这分明就是RxJava换种写法。这种写法我们称作 lambda表达式,是一种链式操作。在filter{}等里面,有一个常量参数it代表当前元素。
用原生的Java写写看:
....//fruit的初始化 Set<String> tempSet = new TreeSet<>(); for(String fruit :fruits){ if(fruit.startWith("a")){ //遍历过程中不能对集合进行增删操作,否则容易出现异常 tempSet.add(fruit); } } fruits.removeAll(tempSet); Collections.sort(fruits); for(String fruit:fruits){ String s = fruit.toUpperCase(); forEach(s); } void forEach(String s){ System.out.println(s); }
12.类的继承和接口
Kotlin在继承类和接口实现上比Java有了很大的区别。其一,实例化对象不用加new。其二,Java写在构造器的参数在Kotlin可以在类声明时在类名后声明。其他的不可描述。fun main(args: Array<String>) { val rectangle = Rectangle(5.0, 2.0) //no 'new' keyword required val triangle = Triangle(3.0, 4.0, 5.0) println("Area of rectangle is ${rectangle.calculateArea()}, its perimeter is ${rectangle.perimeter}") println("Area of triangle is ${triangle.calculateArea()}, its perimeter is ${triangle.perimeter}") } abstract class Shape(val sides: List<Double>) { val perimeter: Double get() = sides.sum() abstract fun calculateArea(): Double } interface RectangleProperties { val isSquare: Boolean } class Rectangle( var height: Double, var length: Double ) : Shape(listOf(height, length, height, length)), RectangleProperties { override val isSquare: Boolean get() = length == height override fun calculateArea(): Double = height * length } class Triangle( var sideA: Double, var sideB: Double, var sideC: Double ) : Shape(listOf(sideA, sideB, sideC)) { override fun calculateArea(): Double { val s = perimeter / 2 return Math.sqrt(s * (s - sideA) * (s - sideB) * (s - sideC)) } }
用Java代码
.... // main函数省略 abstract class Shape{ private double perimeter; Shape(List<Double> sides){ for(Double side :sides){ perimeter+=side; } } abstract double calculateArea(); } interface RectangleProperties { boolean isSquare(); } class Rectangle extends Shape{ double height; double length; Rectangle(double height,double length){ super(Arrays.asList(height,length,height,length)); this.height = height; this.length = length; } @Override boolean isSquare(){ return length = height; } @Override double caculateArea(){ return height*length; } } class Triangle extends Shape{ double sideA; double sideB; double sideC; Triangle(double sideA,double sideB,double sideC){ super(Arrays.asList(sideA,sideB,sideC)); this.sideA = sideA; this.sideB = sideB; this.sideC = sideC; } double caculateArea(){ final double s = perimeter/2; return Math.sqrt(s * (s - sideA) * (s - sideB) * (s - sideC)); } }
对比一下可以发现,Kotlin在类的继承和接口实现的简洁性比Java有了很大的提升。其一、构造器参数在类声明时就已经声明并写入。其二,类声明的参数会被系统直接默认为类成员属性且无需逐个为其赋值。其三、接口可以声明变量常量,并在实现类上赋初值。其四、对象实例化不用加new了。
结语
Kotlin的基础语法与Java的对比上可以看到Kotlin的代码简洁性比Java强上不少。Kotlin为什么可以取代Java成为Android的官方开发语言通过阅读这篇笔记都有所体会吧。由于Kotlin和Java都是运行在JVM虚拟机上,所以两者之间可以互相调用。至于用哪种?你喜欢就好。相关文章推荐
- Java基础语法(一)
- Java 基础语法
- JAVA企业级开发-xml基础语法&约束&解析(04)
- java语言语法基础
- JAVA基础语法考点
- java基础语法学习笔记(三)
- Java语法基础
- Java笔记02-Java语法基础01
- java基础语法学习笔记(四)
- java 基础语法
- Java 基础语法
- JavaSE复习之一 基础知识:Java的基础语法
- (4)2017.8.4-java基础语法和控制流程(中)
- java基础语法
- Java 学习 第二章基础语法
- Java_语法基础_字节数组转换为16进制字符串
- java基础语法
- [Java 基础]基础语法
- 黑马程序员-----java基础语法 函数数组
- java 步步惊心 (一) 基础语法