I have recently stumbled upon SAM (single abstract method) concept in Java.
I program in Scala and to me, they look the same as anonymous functions (or lambdas), however my IntelliJ suggests me to either use SAM or lambdas in different scenarios.
Example 1:
val x = new Function1[Int, Int] { // here usage of lambda is suggested
override def apply(x: Int): Int = x * 2
}
Here lambda usage is suggested.
Example 2:
val event: EventHandler[ActionEvent] = new EventHandler[ActionEvent]() { // here usage of SAM is suggested
override def handle(e: ActionEvent): Unit = {
println("hi")
}
}
I struggle to see the difference in syntax between an anonymous function and a SAM. Are there any conceptual or functional differences between the two?
The syntax is almost the same, the difference is the context.
Function are interfaces supported by language, which allows things like combining 2 functions into one function, are supported by collections etc.
Single Abstract Method is any trait or class which has only one method to implement, and so it would be unambiguous to take this method's signature, turn it into function's signature and let the compiler rewrite such function into an anonymous class instance.
Noticeable differences:
sam1 andThen sam2
unless you somehow add these methods there yourselfI guess you can think of both of them as the same concept - some trait/class with exactly one abstract method initialized using function syntax - where some FunctionX
interface would be the "default" and compiler would inter to it, and some other implementations would require explicit type ascription and be called SAM.
Whether we see SAM as reuse of function syntax, of function as special case of SAM doesn't change the fact that SAM are NOT lambdas/closures/anonymous functions. This name is used only for things intended to be used as functions, that is implementations of function interfaces (Function1
, Function2
, ..., PartialFunction
, etc).
The FunctionN types are special in scala, in that an anonymous function is inferred to be of that type automatically. val twice = (x: Int) => x * 2
is inferred to be a Function1[Int, Int]
, not any other type, unless the expected type is a (different) SAM interface.
If the expected type is a SAM interface -- an interface with a single abstract method -- it will get converted to that type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With