一、lambda与sam
SAM 转换 (Single Abstract Method Conversions): 即SAM 转换就是 kotlin 在调用 java 代码时能使用 Lambda
java中实现了只有一个接口当参数的类
参考:
为什么 Kotlin 调用 java 时可以使用 Lambda?
示例:
/**
* kotlin与java互操作(SAM 转换)
* 1.SAM 是Single Abstract Method是缩写
* 2.SAM转换的条件:Java的接口,只有一个接口当参数的方法,可以使用lambda当参数
* 3.对于实现了kotlin实现的java接口,在java函数中定义该参数后,kotlin引用时可以用lambda表达式使用
* 4.由于java与kotlin表达式并不兼容,所以在每次添加lambda表达式都是不同对象
*/
//java式写法
val button = Button(this)
//匿名内部类
button.setOnClickListener(object : View.OnClickListener {
override fun onClick(view: View?) {
val text = when (view?.id) {
R.id.button1 -> "1"
R.id.button2 -> "2"
else -> "3"
}
println("==========$text=============")
}
})
// public void setOnClickListener(View.OnClickListener l) {}
// public final fun setOnClickListener(l: ((v:View!)->Unit)!): Unit
//sam-constructor
val listener = View.OnClickListener { view ->
val text = when (view.id) {
R.id.button1 -> "1"
R.id.button2 -> "2"
else -> "3"
}
println("==========$text=============")
}
button.setOnClickListener(listener)
//另一种写法
//方法只有一个lambda当作参数,可去掉类型
button.setOnClickListener(View.OnClickListener { view ->
val text = when (view.id) {
R.id.button1 -> "1"
R.id.button2 -> "2"
else -> "3"
}
println("==========$text=============")
})
//如果 Lambda 是一个函数的唯一参数,那么调用这个函数时可以省略圆括号
button.setOnClickListener({ view ->
val text = when (view.id) {
R.id.button1 -> "1"
R.id.button2 -> "2"
else -> "3"
}
println("==========$text=============")
})
//如果 Lambda 所表示的匿名函数只有一个参数,
// 那么可以省略它的声明以及->符号(默认会用it来给省略的参数名命名)
button.setOnClickListener { view ->
val text = when (view.id) {
R.id.button1 -> "1"
R.id.button2 -> "2"
else -> "3"
}
println("==========$text=============")
}
//最简单的kotlin lambda写法
button.setOnClickListener {
val text = when (it.id) {
R.id.button1 -> "1"
R.id.button2 -> "2"
else -> "3"
}
println("==========$text=============")
}
参考: Kotlin修炼指南(二):lambda表达式的精髓
二、lambda表达式 与 匿名内部类实现接口
测试java:
去掉实例对象,只保留参数和语句,并用->连接
()->{}
public class Test {
public static void main(String[] args) {
/*
* 单行
*/
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("11");
}
}).start();
//lambda
new Thread(() -> System.out.println("2")).start();
/*
* 多行
*/
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("12");
System.out.println("13");
}
}).start();
//lambda
new Thread(() -> {
System.out.println("22");
System.out.println("23");
}).start();
/*
* 多参数
*/
List<String> list = Arrays.asList("I", "love", "you", "too");
Collections.sort(list, new Comparator<String>() {// 接口名
@Override
public int compare(String s1, String s2) {// 方法名
if (s1 == null)
return -1;
if (s2 == null)
return 1;
return s1.length() - s2.length();
}
});
// lambda
Collections.sort(list, (s1, s2) -> {// 方法名
if (s1 == null)
return -1;
if (s2 == null)
return 1;
return s1.length() - s2.length();
});
}
}
测试kotlin:
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
/**lambda表达式代替匿名内部类*/
/*
* 单行
*/
Thread(Runnable { println("11") }).start()
//lambda
Thread { println("2") }.start()
/*
* 多行
*/
Thread(Runnable {
println("12")
println("13")
}).start()
//lambda
Thread {
println("22")
println("23")
}.start()
/*
* 多参数
*/
val list = listOf("c#", "c++", "c")
Collections.sort(list, object : Comparator<String> {
override fun compare(s1: String?, s2: String?): Int {
if (s1 == null)
return -1
if (s2 == null)
return 1
return s1.length - s2.length
}
})
println("1 : $list")
// lambda
val list2 = listOf("c#", "c++", "c")
Collections.sort(list2, Comparator { s1, s2 ->
if (s1 == null)
return@Comparator -1
if (s2 == null)
return@Comparator 1
s1.length - s2.length
})
println("2 : $list2")
// lambda2
val list3 = listOf("c#", "c++", "c")
Collections.sort(list3) Comparator@{ s1, s2 ->
if (s1 == null)
return@Comparator -1
if (s2 == null)
return@Comparator 1
s1.length - s2.length
}
println("3 : $list3")
}
三、lambda表达式与接口回调
常见接口回调 :
interface ICallback {
fun onSuccess(msg: String)
fun onFail(msg: String)
}
class NormalCallback {
var mCallback: ICallback? = null
fun setCallback(callback: ICallback) {
mCallback = callback
}
fun init() {
mCallback?.onSuccess("success message")
}
}
private fun test() {
val normalCallback = NormalCallback()
normalCallback.setCallback(object : ICallback {
override fun onSuccess(msg: String) {
println("常见接口回调 onSuccess : $msg")
}
override fun onFail(msg: String) {
println("常见接口回调 onFail : $msg")
}
})
normalCallback.init()
}
//常见接口回调 onSuccess : success message
lambda表达式测试1:一个回调
class TestCallbackA {
var mCallBack: ((str: String) -> Unit)? = null
fun setCallback(myCallBack: ((str: String) -> Unit)) {
this.mCallBack = myCallBack
}
}
private fun testA() {
val testCallbackA = TestCallbackA()
testCallbackA.setCallback {
println("callback : $it")
}
}
lambda表达式测试2:多回调
class TestCallbackB {
var mSuccessCallback: (String) -> Unit? = {}
var mFailCallback: (String) -> Unit? = {}
fun setCallback(successCallback: (String) -> Unit,
failCallback: (String) -> Unit) {
this.mSuccessCallback = successCallback
this.mFailCallback = failCallback
}
fun init() {
mSuccessCallback("b success message")
mFailCallback("b fail message")
}
}
private fun testB() {
val testCallbackB = TestCallbackB()
testCallbackB.setCallback({
println("b success : $it")
}, {
println("b failure : $it")
})
testCallbackB.init()
}
lambda表达式测试3:多参数
// private var mListener1: ((Int, String) -> Unit)? = null
// private var mListener2: ((a: Int, b: String) -> Unit)? = null
// private var mListener3: ((a: Int, b: String) -> Unit)? = { _, _ -> }
// private var mListener4: (a: Int, b: String) -> Unit = { _, _ -> }
class TestCallbackC {
var mSuccessCallback: (String, Boolean) -> Unit? = { _, _ -> }
var mFailCallback: (String) -> Unit? = {}
fun setCallback(successCallback: (String, Boolean) -> Unit,
failCallback: (String) -> Unit) {
this.mSuccessCallback = successCallback
this.mFailCallback = failCallback
}
fun init() {
mSuccessCallback("c success message", false)
mFailCallback("c fail message")
}
}
private fun testC() {
val testCallbackC = TestCallbackC()
testCallbackC.setCallback({ a, b ->
println("c success : $a - $b")
}, {
println("c failure : $it")
})
testCallbackC.init()
}