IDEA
Kotlin 提供了很多便利,简化了java很多模式化代码。有人说可读性相对较差,习惯之后,会觉得Java不好读。比如:中文思维会觉得英语很难理解,相反而至。每个都要敲代码,磨刀不误砍柴工。泛型如果用好还是有难度的。kt 会越来月流行,不是因为它很强大,而是谷歌在推kotlin,没办法。就说AS 和 eslipse 哪个会一定更好用,并没有。越来越多是kotlin的支持,人世有代谢往来成古今江山留胜迹,我辈复登临。kotlin比java更灵活,移动端不需要那么多并发量。kotlin更像js代码。蹭java 的热度,有有自己的语言,有话语权。移动端开发和前端开发将会有越来越多共同的技术,提升开发效率,降低成本,大势所趋,界面用户体验上的逻辑。新技术出来,天然的抵触,不断的调整心态,新的技术去了解,动向,kotlin 大势所趋,必须学。IT行业,不断有年轻人进入的行业,我们要追随年轻人的脚步。在算法中,函数编程用的比较多。kotlin最大的好处就是支持kotlin和java混编。
直接上项目,用到的知识点只是40%,
print(ere("jjj"))
private fun `ere`(name: String, age: Int = 2) {
print(name + age)
}
val total:Int="Mississippo".count()
val totals:Int="Mississippo".count { letter -> letter == 's' }
print(total) 11
print(totals) 4
匿名函数不需要return关键字返回数据,会自动返回最后一行语句的结果
//变量的类型是个匿名函数,无参,返回值是String
val result: () -> String
result = {
val name = "aaaaa"
"$name"
}
//声明的时候赋值
val result: () -> String = {
val name = "aaaaa"
"$name"
}
val result: (Int) -> String = { age ->
val name = "aaaaa"
"$name $age"
}
val result: (Int) -> String = {
val name = "aaaaa"
"$name $it"
}
//类型推断
val result = { age:Int ->
val name = "aaaaa"
"$name $age"
}
print(result(5)) aaaaa 5
//eg2
showOnBoard("苹果") { goodsName: String, hour: Int ->
"$goodsName$hour"
}
fun showOnBoard(goodsName: String, getDiscountWords: (String, Int) -> String) {
val hour = (1..24).shuffled().last()
print(getDiscountWords(goodsName, hour))
}
val getDiscountWords = { goodsName: String, hour: Int ->
"$goodsName$hour"
}
showOnBoard("苹果", getDiscountWords)
inline fun showOnBoard(goodsName: String, getDiscountWords: (String, Int) -> String) {
val hour = (1..24).shuffled().last()
print(getDiscountWords(goodsName, hour))
}
showOnBoard("苹果", ::getDiscountWords)
fun getDiscountWords(goodsName: String, hour: Int): String {
return "$goodsName$hour"
}
fun showOnBoard(goodsName: String, getDiscountWords: (String, Int) -> String) {
val hour = (1..24).shuffled().last()
print(getDiscountWords(goodsName, hour))
}
//eg1
getFullName("aa", result = {
print(it)
})
getFullName("aa") {
print(it)
}
fun getFullName(name: String, result: (count: Int) -> Unit) {
result.invoke(name.count())
}
public class aaa {
public static void main(String[] args) {
getFullName("aa", new Result() {
@Override
public void getResult(int count) {
System.out.println(count);
}
});
}
public interface Result{
void getResult(int count);
}
public static void getFullName(String name,Result result) {
result.getResult(name.length());
}
}
substring
const val NAME = "Jimmy's friend"
var index = NAME.indexOf('\'')
// var str = NAME.substring(0, index)
var str = NAME.substring(0 until index)
print(str) Jimmy
split 返回list集合数据,list集合支持 解构语法特性 ,其常用简化变量的赋值
const val NAME = "Jimmy,Jim,Bob"
val str =NAME.split(",")
var (one:String,two:String,three:String) =NAME.split(",")
println(str) [Jimmy, Jim, Bob]
println("$one $two $three") Jimmy Jim Bob
//跳过某个值,不会赋值,提高代码运行效率
val list = mutableListOf<String>("aa", "bb", "cc")
val (one: String, _: String, three: String) = list
print("$one $three") aa cc
replace 比java更加强大
const val NAME = "The people's republic China."
fun main() {
val str=NAME.replace(Regex("[ae]")){
when (it.value){
"a"->"8"
"e"->"6"
else -> it.value
}
}
println(str) Th6 p6opl6's r6public Chin8.
}
字符串比较 (内存分配) , == 检查两个字符串中的字符是否匹配,(相当于java中的equals); === 检查两个变量是否指向内存堆上同一对象相当于java中的==)
val str1="aa"
val str2="aa"
println(str1==str2) true
println(str1===str2) true
val str1="Aa"
val str2="aa".capitalize()
println(str1==str2) true
println(str1===str2) false
double 转int,double 格式化
//保留两位小数 ,四舍五入
val aa = 200.28212
print( "%.2f".format(aa))
let
fun formatGreeting(guestName: String?): String {
return guestName?.let { "Welcome,$it" } ?: "What's your name?"
}
print(formatGreeting(null)) What's your name?
run(可执行引用函数,链式调用)
var file = File("D://demo//111//readme.txt")
val result = file.run { readText().contains("great") }
print(result) true
fun isLong(name: String) = name.length >= 10
fun showMessage(isLong: Boolean): String {
return if (isLong) {
"Name is too long"
} else {
"Please rename"
}
}
"D://demo//111//readme.txt".run(::isLong).run(::showMessage).run(::print)
run 和with 传参方式不一样
val result = "aaaaaa".run { length > 3 }
val result = with("aaaaaa"){
length > 3
}
alse (我也)返回接收者对象
var fileContents: List<String>
File("D://demo//111//readme.txt")
.also { println(it.name) }
.also { fileContents = it.readLines() }
println(fileContents)
readme.txt
[great good]
takeif 如果需要判断某个条件是否满足,再决定是否可以赋值变量或者执行某项任务
val result= File("D://demo//111//readme.txt")
.takeIf { it.exists() && it.canRead() }
?.readText()
println(result) great good
//不存在
val result= File("E://demo//111//readme.txt")
.takeIf { it.exists() && it.canRead() }
?.readText()
println(result) null
list 通过安全索引函数 获取元素
val list = listOf<String>("aa", "bb", "cc")
println(list.getOrElse(3) { "unknow" }) unknow
println(list.getOrNull(3) ?: "unknow") unknow
mutable 函数
val list = mutableListOf<String>("aa", "bb", "cc")
//运算符重载
// list.add("dd")
list += "dd"
//list.remove("dd")
list -= "dd"
//如果此值符合条件,则移除
list.removeIf { it.contains("aa") }
//可变和不变相互转换
list.toList().toMutableList()
list 索引遍历
list.forEachIndexed { index, s -> }
set 不可重复,elementAt,其余的都和list用户一致
val set = setOf<String>("aa", "bb")
print(set.elementAt(0))
list 转set 去除重复元素 去重
val list = listOf<String>("aa", "bb","bb")
//print(list.toSet().toList())
//快捷函数
print(list.distinct())
数组类型提供各种array 是引用类型,最终编译成java基本数据类型
map,其它操作写法和list大概一致,to 相当于Pair() 函数
val map = mapOf("aa" to 20, "bb" to 30)
mapOf(Pair("aa", 20), Pair("bb", 30))
println(map["aa"]) 20
println(map.getValue("aa")) 20
println(map.getOrElse("cc"){"qq"}) qq
println(map.getOrDefault("cc",0)) 0
map 遍历
val map = mapOf("aa" to 20, "bb" to 30)
map.forEach {
println("${it.key},${it.value}")
}
map.forEach { (key: String, value: Int) ->
println("$key,$value")
}
map 添加元素 getOrPut
val map = mutableMapOf("aa" to 20, "bb" to 30)
map += "cc" to 40
map["cc"] = 40
//如果没有则增加
map.getOrPut("dd") { 50 }
println(map)
field 覆盖get、set
class Player {
var name: String = "j a ck"
get() = field.capitalize()
set(value) {
//去掉前后空格
field=value.trim()
}
}
fun main() {
var p=Player()
println(p.name)
p.name=" tom "
println(p.name)
}
主构造函数
import kotlin.math.absoluteValue
class Player(_name: String, _age: Int) {
//临时变量只用一次的用下划线
//get和set紧跟属性,private说明name只读不可以改变
var name = _name
get() = field.capitalize()
private set(value) {
field = value.trim()
}
var age = _age
get() = field.absoluteValue
set(value) {
field = field.absoluteValue
}
}
fun main() {
val p=Player("Tom", 30)
}
在主构造函数里定义属性
class Player(_name: String, var age: Int) {
//临时变量只用一次的用下划线
//get和set紧跟属性,private说明name只读不可以改变
var name = _name
get() = field.capitalize()
private set(value) {
field = value.trim()
}
}
fun main() {
val p=Player("Tom", 30)
}
次构造函数 constructor
class Player(_name: String, var age: Int) {
//临时变量只用一次的用下划线
//get和set紧跟属性,private说明name只读不可以改变
var name = _name
get() = field.capitalize()
private set(value) {
field = value.trim()
}
constructor(name:String):this(name,100){
this.name=name.toUpperCase()
}
}
初始化块 init { }
init {
require(age>10){"age must be positive"}
}
val p=Player("Tom",9)
初始化顺序
1.著构造函数离声明的属性
2.类级别的属性赋值
3.init初始化块里的属性赋值和函数调用
4.此构造函数里的属性赋值和函数调用
延迟初始化 lateinit,用它的时候再初始化
fun main() {
var user = User()
// user.ready()
user.battle()
}
class User {
lateinit var equipment: String
fun ready() {
equipment = "knife"
}
fun battle() {
//健壮的语言
if (::equipment.isInitialized)
println(equipment)
}
}
惰性初始化 by lazy 延迟记载
fun main() {
var user = User()
Thread.sleep(3000)
user.config
}
class User {
//懒汉式
val config by lazy { loadConfig() }
//饿汉式,一上来就记载
//val config =loadConfig()
private fun loadConfig(): String {
println("loading...")
return "xxx"
}
}
初始化陷阱1-按照顺序来编译,顺序不能写反
class User {
val blood = 100
init {
val bloodBonus = blood.times(4)
}
}
初始化陷阱2-按照顺序来编译,顺序不能写反
class User {
val name: String
private fun firstLetter() = name[0]
init {
//一下两个顺序不能反
name = "Jack"
println(firstLetter())
}
}
如果继承类,就要用open来修饰;如果子类需要覆盖父类函数,也需要open来修饰
open class Product(val name:String){
open fun load()="Nothing.."
}
class AA:Product("aa"){
override fun load()="xxxxx......"
}
fun main(){
val p:Product=AA()
println(p.load())
//类型检测 is
println(p is Product)
}
智能类型转换 as,转一次则后面可以直接使用
Any 超类,任意类型 都是Any类 ,Kotlin的跨平台比java更好
object 关键字
单例对象:防止浪费资源;方便管理状态,因为只有一份。
//单例对象
object ApplicationConfig{
}
//打印同一个对象
print(ApplicationConfig)
print(ApplicationConfig)
伴生对象 companion
open class configMap{
companion object{
private const val PATH="xxxx"
fun load()=File(PATH).readBytes()
}
}
fun main(){
//比javastatic更加人性化,不调用,则不执行
ConfigMap.load()
}
嵌套类
class Player2{
class Equipment(var name:String){
fun show=println("equipmeng:$ name")
}
}
fun main(){
Player2.Equipment("knife").show()
}
数据类 data 专门存数据的类 ,提供 toString / copy(new了新对象,陷阱:不用次构造) / 解构语法
data class Coordinate(var x:Int,var y:Int){
val isInBounds= x>0
}
fun main(){
//比较属性的值
println(Coordinate(10,20)==Coordinate(10,20)) true
}
解构声明
//必须以下写法
class PlayerScore(val experience:Int,val level:Int){
operator fun component1()=experience
operator fun component1()=level
}
fun main(){
val(x,y)=PlayerScore(10,20)
print("$x $y")
}
//数据类支持解构语法
data class PlayerScore(val experience:Int,val level:Int)
fun main(){
val(x,y)=PlayerScore(10,20)
print("$x $y")
}
运算符重载
data class PlayerScore(val x:Int,val y:Int){
operator fun plus(other:PlayerScore)=PlayerScore(x+other.x,y+other.y)
}
fun main(){
val a=PlayerScore(10,20)
val b=PlayerScore(10,20)
println(a+b)
}
枚举类 特殊类 可以定义函数
enum class Direction(private val score:PlayerScore){
EAST(PlayerScore(1,2)),
WEST(PlayerScore(3,2);
fun updateScore(two:PlayerScore)=PlayerScore(two.x+score.x , two.y+score.y)
}
fun main(){
print(Direction.EAST) EAST
print(Direction.EAST.updateScore(PlayerScore(10,10))) PlayerScore(x=11,12)
}
代数数据类型 ADT 条件固定,else省略
enum class Direction{
EAST,
WEST;
}
class DD(var a:Direction){
fun check():String{
retrun when(a){
Direction.EAST ->"东"
Direction.WEST ->"西"
}
}
}
密封类 sealed 里面包含很多类,遇到太复杂的枚举(某个状态需要又个属性 ),则衍生出密封类
enum class Direction{
object EAST:Direction(),
class WEST( val str:String):Direction();
}
class DD(var a:Direction){
fun check():String{
retrun when(a){
is Direction.EAST ->"东"
is Direction.WEST ->"西${t(his.a as WEST).str}"
}
}
}
interface 默认open,实现使用overrided,默认实现
interface Movable{
val maxSpeed:Int
get()=(1..500).shuffled().last()
var wheels:Int
fun move(movable:Movable):String
}
class Car(name:String,override var wheels:Int=4):Movable{
override var maxSpeed:Int
get()=super.maxSpeed
set(value){}
override fun move(movable:Movable):String{
}
}
抽象类 abstract (和Java一样):既可以有实现的函数也可以有没实现的函数
java多重继承是通过实现接口,再继承;
abstract class Gun(val range:Int){
abstract fun pullTrigger():String
}
class AK47(val price:Int):Gun(50){
override fun pullTrigger(): String {
TODO("Not yet implemented")
}
}`在这里插入代码片`
模板代码放在父类泛型就可以搞定了
泛型 T是Type的简写
class MagicBox<T>(item: T) {
private var subject: T = item
}
class Boy(val name:String,val age:Int)
class Dog(val weight:Int)
fun main() {
val box1=MagicBox(Boy("Tom",10))
}
泛型函数
class MagicBox<T>(item: T) {
private var subject: T = item
var avaliable = false
//泛型函数
fun fetch(): T? {
return subject.takeIf { avaliable }
}
}
class Boy(val name: String, val age: Int)
fun main() {
val box1 = MagicBox(Boy("Tom", 10))
box1.avaliable=true
box1.fetch()?.run {
//run 返回lamble 的执行结果
print("you find $name")
}
}
多泛型参数 R 是return的缩写 ,泛型用好不容易
class MagicBox<T>(item: T) {
private var subject: T = item
var avaliable = false
//泛型函数
fun fetch(): T? {
return subject.takeIf { avaliable }
}
//魔盒放的是男孩,取出来把男孩变成男人;把元素进行修改
fun <R> fetch(subjectMethod: (T) -> R): R? {
return subjectMethod(subject).takeIf { avaliable }
}
//运算符重载
operator fun get(index: Int): T? = subject[index]?.takeIf { avaliable }
}
class Boy(val name: String, val age: Int)
class Man(val name: String, val age: Int)
fun main() {
val box1 = MagicBox(Boy("Tom", 10))
box1.avaliable = true
val man= box1.fetch {
Man(it.name,it.age.plus(15))
}
}
如果能使用这些高级特性,说明很牛批了
子类泛型对象可以赋值给父类泛型对象,用out
父类泛型对象可以赋值给子类泛型对象,用in
out(协变)kotlin特有的,泛型类型作为函数的返回
in(逆变)kotlin特有的,
invariant(不变)kotlin特有的,
interface Production<out T> {
fun product(): T
}
interface Consumer<in T> {
fun consumer(item: T)
}
interface ProductConsumer<T> {
fun product(): T
fun consumer(item: T)
}
open class Food
open class FastFood : Food()
class Burger : FastFood()
//生产者
//食品商店
class FoodStore : Production<Food> {
override fun product(): Food {
print("Product Food")
return Food()
}
}
//快餐商店
class FastStore : Production<FastFood> {
override fun product(): FastFood {
print("Product Fast")
return FastFood()
}
}
//汉堡商店
class BurgerStore : Production<Burger> {
override fun product(): Burger {
print("Product Burger")
return Burger()
}
}
//消费者
class Everybody:Consumer<Food>{
override fun consumer(item: Food) {
print("eat food")
}
}
class ModernPeople:Consumer<FastFood>{
override fun consumer(item: FastFood) {
print("eat FastFood")
}
}
class American:Consumer<Burger>{
override fun consumer(item: Burger) {
print("eat Burger")
}
}
fun main() {
//赋值
//子类泛型对象可以赋值给父类泛型对象,用out
val production1: Production<Food> = FoodStore()
println(production1.product())
val production2: Production<Food> = FastStore()
val production3: Production<Food> = BurgerStore()
//父类泛型对象可以赋值给子类泛型对象,用in ,Everybody的泛型对象类型是Food,Food是Burger的父类
val consumer1:Consumer<Burger> =Everybody()
val consumer2:Consumer<Burger> =ModernPeople()
val consumer3:Consumer<Burger> =American()
}
如果你想知道某个泛型参数具体是 什么类型,reified关键字可以帮助你检查泛型参数类型。kotlin不允许对泛型参数T做类型检查,因为泛型参数类型会被类型擦除。
open class Human(val age: Int)
class Boy(val name: String, age: Int) : Human(age)
class Man(val name: String, age: Int) : Human(age) {
override fun toString(): String {
return "Man(name=$name,age=$age)"
}
}
class MagicBox2<T : Human>() {
//随机生成一个对象,如果不是指定对象,就通过backup生成一个对象
//kotlin 不允许泛型作为类型检查,除非 inline fun <reified T>
inline fun <reified T> randomOrBackUp(backup: () -> T): T {
val items = listOf(Boy("Jack", 10), Man("Tom", 30))
val random = items.shuffled().first()
return if (random is T) {
random
} else {
backup()
}
}
}
fun main() {
val box1: MagicBox2<Man> = MagicBox2()
val subject: Man = box1.randomOrBackUp {
Man("Bob", 40)
}
println(subject)
//随机输出
//Man(name=Tom,age=30)
//Man(name=Bob,age=40)
}
扩展可以在不直接修改类定义的情况下增加类的功能
fun String.addExt(amount: Int = 1): String {
return this + "!".repeat(amount)
}
fun String.addExt(amount: Int = 1)= this + "!".repeat(amount)
println("abc".addExt(2)) abc!!
链式调用
fun Any.easyPrint(): Any {
println(this)
return this
}
fun String.addExt(amount: Int = 1) = this + "!".repeat(amount)
( "abc".easyPrint() as String).addExt(2).easyPrint()
//输出:
abc
abc!!
超类上定义扩展函数-细思极恐
泛型扩展函数(使用范围更广)
标准函数和泛型扩展函数
fun <T> T.easyPrint(): T {
println(this)
return this
}
fun String.addExt(amount: Int = 1) = this + "!".repeat(amount)
( "abc".easyPrint() as String).addExt(2).easyPrint()
//输出:
abc
abc!!
扩展属性
//统计有多少个元音字母
val String.numVowels
get() = count { "aeiou".contains(it) }
println("aaa".numVowels) 3
可空类扩展 infix
函数式编程带来的好处
fun String?.printDefault(default:String)= print(this?:default)
val aa:String?=null
aa.printDefault("11111") 11111
infix fun String?.printDefault(default:String)= print(this?:default)
val aa:String?=null
aa printDefault "abc"
定义扩展文件
package extension
fun<T> Iterable<T>.randomTake():T=this.shuffled().first()
使用
import extension.randomTake
fun main(){
list.randomTake()
}
重命名扩展
import extension.randomTake as APPLE
list.APPLE()
通常以s结尾 如:Sequences.kt Rangs.kt Maps.kt
apply 函数如果做到支持接收者对象的隐式调用的。T.() 泛型类型的匿名函数
使用泛型类型匿名函数内部this指向泛型类型的对象,调用它的隐私调用
import java.io.File
//扩展函数(count()=this.count() 隐式调用)
fun String.addExt(amount: Int = 1) = this + "!".repeat(count())
//泛型扩展函数
fun <T> T.easyPrint():Unit = print(this)
//为什么要传入泛型的扩展函数、而不是普通的匿名函数
// T.() ->Unit 扩展函数也可以是匿名函数,匿名函数也可以是扩展韩式
//匿名函数内部this指向一个File对象,隐式调用
//扩展函数自带了接收者对象的this隐式调用
//为什么是泛型的扩展函数
public inline fun <T> T.apply(block: T.() -> Unit): T {
block()
return this
}
fun main() {
val file = File("xx").apply {
//file 隐式调用
setReadable(true)
}
}
// fix 等于 匿名函数 () -> Unit
fun foSomething(fix: () -> Unit) {
}
不是泛型扩展函数,比如以下只支持FIle扩展函数
public inline fun <File> File.apply(block: File.() -> Unit): File {
block()
return this
}
fun main() {
val file = File("xx").apply {
//file 隐式调用
setReadable(true)
}
}
//分解一下
//1.定义一个扩展函数
fun File.ext(): Unit {
setReadable(true)
}
//2.给block变量赋值
val block = File::ext
//3.传入apply函数
File("xx").apply { block }
范式:套路或者习惯
函数式编程 在学术;高阶函数,以函数为参数或返回函数;
函数类别(由三大类函数构成)
变换transform 过滤 filter 合并combine;针对集合数据类型,目标是产生一个最终结果;
新技术出来,天然的抵触,不断的调整心态,新的技术去了解,动向,kotlin 大势所趋,必须学。
IT行业,不断有年轻人进入的行业,我们要追随年轻人的脚步。
1.激进派2.顽固派
最常用的:map flatmap(操作集合的集合,多个集合中元素合并,返回一个集合)
变量不用变来变去
val list = listOf("aa", "bb")
list.map { item -> "A baby $item" }
.map { it -> it.length > 1 }
print(list)
val list = listOf(listOf(1, 2, 3), listOf(4, 5, 6))
val result = list.flatMap { it }
println(result) [1, 2, 3, 4, 5, 6]
过滤函数接收一个predicate 函数
过滤集合中元素含有"J"字母的元素
val result=list.filter { it.contains("J") }
print(result) ["Jack", "Jime"]
找包含red的
val list = listOf(
listOf("red apple", "green apple", "blue apple"),
listOf("red fish", "blue fish"),
listOf("yellow banana", "teal banana")
)
val result = list.flatMap { it.filter { it.contains("red") } }
print(result) ["red apple",red fish"]
找素数,none所有的不能为0
val number = listOf(7, 4, 8, 4, 3, 22, 18, 11)
val result = number.filter { number -> (2..number).map { number % it }.none { it == 0 } }
print(result) [7,3,11]
合并函数:将不同的集合合并成一个新的集合
zip:合并两个集合,返回一个包含键值对的新集合
val employee = listOf("Jack", "Jason", "Tomy")
val ages = listOf(10, 20, 30)
val employeeAges = employee.zip(ages).toMap()
print(employeeAges["Jack"]) 10
fold 接受一个初始累加器值,随后根据匿名函数的结果更新;initial 初始累加器的值
遍历一个集合元素,将每个元素乘以3,然后累加
val foldedValue = listOf(1, 2, 3, 4).fold(initial = 0) { accmulator: Int, number: Int ->
println("$accmulator")
accmulator + number * 3
}
println("$foldedValue")
//输出结果
0
3
9
18
30
List shirtsSize = Arrays.asList("large", "x-large", "medium");
Map employeesShirtSizes = new HashMap<>();
for (int i = 0; i < employees.size(); i++) {
employeesShirtSizes.put(employees.get(i), shirtsSize.get(i));
}
List formattedList = new ArrayList<>();
for (Map.Entry entry : employeesShirtSizes.entrySet()) {
formattedList.add(String.format("$s,shirt size :$s", entry.getKey(), entry.getValue()));
}
System.out.println(formattedList);
//输出结果
[Jason,shirt size:x=large,Jack,shirt zie:large,Tomy,shirt zie:medium]
kotlin 写法
val employees = listOf("Jack", "Jason", "Tomy")
val shirtsSize = listOf("large", "x-large", "medium")
val employeesShirtSizes = employees.zip(shirtsSize).toMap()
val list = employeesShirtSizes.map { "${it.key},shirt size:${it.value}" }
println(list)
内置惰性集合类型,序列里的值可能有无限多
generateSequence
产生头1000个素数
普通方法
//产生头1000个素数
//有1000个数据的集合
val toList=(1..5000).toList().filter{it.isPrime()}.take(1000)
println(toList.size) 570
//扩展函数
fun Int.isPrime():Boolean{
(2 until this).map{
if(this % it == 0){
return false
}
}
return true
}
使用序列查找素数
//从2开始
val oneTousandPrimes:Sequence<Int> = generateSequence(2){value ->
value + 1
}.filter{it.isPrime()}.take(1000)
println(oneTousandPrimes.toList().size) 1000
//扩展函数
fun Int.isPrime():Boolean{
(2 until this).map{
if(this % it == 0){
return false
}
}
return true
}
注解@NotNull 一定不为空
注解@Nullable 可能为空
public class Jhava{
@NotNull
public String utterCreeting(){
return "HELLOW";
}
@Nullable
public String determin(){
return null;
}
private int hitPoints=12312
public String getHitPoints(){
return hitPoints;
}
public void setHitPoints(int hitPoints){
this.hitPoints=hitPoints;
}
}
String! 平台类型
fun main(){
val adversary=Jhave()
println(adversary.utterCreeting()) HELLOW
val level:String!=adversary.determin() 没报错
adversary.determin().toLowerCase() 空指针异常
level?.toLowerCase() 没报错
}
类型映射
最后都会变成java 类型
.属性名字
//接上面
val adversary=Jhave()
//set
adversary.hitPoints=1
//get
adversary.hitPoints
java 调用 kotlin
方法1
HeroKt.kt
fun makeProclamation()="Greetings,beast!"
java
HeroKt.makeProclamation()
方法2 @file:JvmName()
HeroKt.kt
@file:JvmName("Hero")
fun makeProclamation()="Greetings,beast!"
java
Hero.makeProclamation()
方法1
class Spellbook{
val spells = listOf("AAA","BBB")
}
Spellbook spellbook=new Spellbook ();
spellbook.getSpells();
方法2
class Spellbook{
@JvmField
val spells = listOf("AAA","BBB")
}
Spellbook spellbook=new Spellbook ();
spellbook.getSpells();
kotlin 提供带有默认参数的函数
//调用者可以指定英雄左手或右手拿什么食物,或者使用默认的配置左手拿苹果,右手拿牛肉
@JvmOverloads
fun handOverFood(leftHand:Stirng="apples",rightHand:String="beef"){
println("$leftHand $rightHand")
}
java中调用kotlin
Hero.handOverFood("pear")
@JvmField 注解还能用来以静态的方式提供伴生对象里定义的值
@JvmStatic注解的作用类似于@JvmField ,允许直接调用伴生对象里的函数
class Spellbook{
compaoion object{
@JvmField
val MAX_SPELL_COUNT=10
@JvmStatic
fun getSpellGretting()=print("aaaaaa")
}
}
java调用
Spellbook.MAX_SPELL_COUNT;
Spellbook.getSpellGretting();
@Throws(IOException::class)
fun acceptApology() {
throw IOException()
}
aaaa.extengHandle()
public void extengHandle() throws IOException{
throw new RuntimeException();
}
try{
extengHandle();
}catch(IOException e){
e.printStackTrace();
}
jdk 8之前不支持lamble, Function1代表参数有一个 直到Function 22
//变量=匿名函数
//将其改成小写字母,再大写第一个字符,最后打印字符串
val translator = { aa: String ->
println(aa.toLowerCase().capitalize())
}
Function1<String, Unit> translator= PlayerKt.getTranslator();
translator.invoke("TRUE");