-
高阶函数
函数参数包含函数类型或者返回值包含函数类型
public inline fun IntArray.forEach(action: (Int) -> Unit): Unit { for (element in this) action(element) } 复制代码
// 示例代码 intArrayOf(1, 1).map{"value = $it"}.forEach(::print) // 具体实现 // transform 函数类型:(Int)-> String public inline fun <R> IntArray.map(transform: (Int) -> R): List<R> { return mapTo(ArrayList<R>(size), transform) } // mapTo 函数 是将原Int数组转换成String数组 public inline fun <R, C : MutableCollection<in R>> IntArray.mapTo(destination: C, transform: (Int) -> R): C { for (item in this) destination.add(transform(item)) return destination } 复制代码
-
内联函数
需要使用
inline
关键字,一般是高阶函数使用,作用是将lambda表达式替换为实际的代码,避免创建对象intArrayOf(1, 1).map{"value = $it"}.forEach(::print) 复制代码
反编译看源码,Tools->Kotlin->Show Kotlin ByteCode ->Decompile
// 实际代码 int[] $this$map$iv = new int[]{1, 1}; int $i$f$forEach = false; Collection destination$iv$iv = (Collection)(new ArrayList($this$map$iv.length)); int $i$f$mapTo = false; int[] var5 = $this$map$iv; int var6 = $this$map$iv.length; // 重新创建集合 for(int var7 = 0; var7 < var6; ++var7) { int item$iv$iv = var5[var7]; int var10 = false; String var12 = "value = " + item$iv$iv; destination$iv$iv.add(var12); } Iterable $this$forEach$iv = (Iterable)((List)destination$iv$iv); $i$f$forEach = false; Iterator var2 = $this$forEach$iv.iterator(); // 遍历集合并打印 while(var2.hasNext()) { Object element$iv = var2.next(); int var15 = false; boolean var16 = false; System.out.print(element$iv); } 复制代码
-
local return
intArrayOf(1, 2, 3).forEach { if (it == 1) // 当元素==1时,结束本次的forEach return@forEach println(it) } // 上述等价写法: val intArrayOf = intArrayOf(1, 2, 3) for (element in intArrayOf) { if (element == 1) continue print(element) } 复制代码
-
non-local return
inlineTest { println("") // 此处直接return main方法 return } println("main end") inline fun inlineTest(block1: () -> Unit) { block1() } 复制代码
-
noinline
内联函数的有多个函数参数,并且某一个函数参数不需要内联时可以使用noinline
-
crossinline
因为inline会存在local return 和 non-local return的情况,在下面情况会存在误解
fun main() { inlineTest { println("") return } println("main end") } inline fun inlineTest(block1: () -> Unit) { thread { // 编译报错 block1() } } 复制代码
处理方法
fun main() { inlineTest { println("") // local return return@inlineTest } println("main end") } // 添加crossinline关键字 inline fun inlineTest(crossinline block1: () -> Unit) { thread { block1() } } 复制代码
-
-
let run also apply use
-
let run
最后一行非赋值代码是闭包的返回值,否则返回Unit。
-
also apply
返回值为当前对象
-
use 自动关闭资源
File("ktpractice.iml").inputStream().reader().buffered() .use { var line: String while (it.readLine().also { line = it } != null) { println(line) } } 复制代码
-
-
集合变换与序列
-
filter 过滤
-
map 映射
-
flatMap 变换
元素映射为集合,将集合拼接为新集合
-
sum
-
reduce
fun main() { val list = arrayListOf(1, 2, 3, 4) val reduce = list.reduce { acc, i -> acc + i } println(reduce) } // 输出 10 复制代码
-
fold 初始值和拼接操作
fun main() { val list = arrayListOf(1, 2, 3, 4) val fold = list.foldRight(StringBuilder()) { i, acc -> acc.append(i) } println(fold) } // 输出 4321 复制代码
-
懒序列
val list = arrayListOf(1, 2, 3, 4) val map = list.filter { print("$it ") it % 2 == 0 }.map { print("$it ") it + 1 } println("result: $map") // 输出 filter: 1 filter: 2 filter: 3 filter: 4 map: 2 map: 4 result: [3, 5] 复制代码
相比于上面,懒序列多了asSequence()
fun main() { val list = arrayListOf(1, 2, 3, 4) val map = list.asSequence().filter { print("$it ") it % 2 == 0 }.map { print("$it ") it + 1 } println("result: $map") } // 输出map的地址, 复制代码
遇到terminal operator 才会生成结果
fun main() { val list = arrayListOf(1, 2, 3, 4) list.asSequence().filter { println("filter: $it ") it % 2 == 0 }.map { println("map: $it ") it + 1 }.forEach(::println) } // 输出: filter: 1 filter: 2 map: 2 3 filter: 3 filter: 4 map: 4 5 复制代码
-
-
SAM(single abstract method)转换
-
案例
-
统计字符个数
File("ktpractice.iml").readText().toCharArray() .filterNot(Char::isWhitespace) .groupBy { it } .map { it.key to it.value.size } .sortedByDescending { it.second } .forEach(::println) 复制代码
-
HTML DSL
public class WeekQuery { private static final String TIME_TEMPLATE = "(day between '%s' and '%s')"; private int mYear; private int mWeek; public WeekQuery(int year, int week) { mYear = year; mWeek = week; } public String getWhereClause() { LocalDate firstMondayOfYear = Stream.iterate(LocalDate.of(mYear, 1, 1), date -> date.plusDays(1)) .limit(7) .filter(date -> date.getDayOfWeek() == DayOfWeek.MONDAY) .collect(Collectors.toList()) .get(0); LocalDate destMondayOfYear = firstMondayOfYear.plusWeeks(mWeek - 1); return String.format(TIME_TEMPLATE, destMondayOfYear, destMondayOfYear.plusDays(6)); } public static void main(String[] args) { for (int i = 1; i < 55; i++) { WeekQuery weekQuery = new WeekQuery(2018, i); System.out.println(i + "周 " + weekQuery.getWhereClause()); } showWeeks(1, 55); } public static void showWeeks(int initWeek, int weeks) { LocalDate initData = LocalDate.of(2018, 1, 1).plusWeeks(initWeek - 1); Stream.iterate(initData, date -> date.plusDays(7)) .limit(weeks) .map(day -> day + "~" + day.plusDays(6)).forEach(System.out::println); } } 复制代码
-
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END