Definition of partial function
1) It is a good choice to use disk function when performing logical operations on conditions that meet certain conditions rather than all conditions
2) Encapsulate a group of case statements wrapped in braces as functions, which we call partial functions. It only calculates the parameters that will act on the execution type or the parameters within the specified range, and the values beyond the range will be ignored (not necessarily ignored. See the specific logic)
3) Partial function is a special partial function in scala
Put forward a demand and cause thinking
Give you a set val list = List(1, 2, 3, 4, "abc"), please complete the following requirements:
All numbers in the set list are + 1 and a new set is returned
It is required to ignore non numeric elements, that is, the returned new set form is (2, 3, 4, 5)
Solution - filter + map returns a new set and leads to the partial function
Solution - pattern matching
object PartialFunDemo01 { def main(args: Array[String]): Unit = { //Idea 1 filter + map solution //Although it can solve the problem, it is troublesome val list = List(1, 2, 3, 4, "hello") // Filter first, then map println(list.filter(f1).map(f3).map(f2)) //Idea 2 - pattern matching //Summary: Although using pattern matching is relatively simple, it is not perfect val list2 = list.map(addOne2) println("list2=" + list2) } //pattern matching def addOne2( i : Any ): Any = { i match { case x:Int => x + 1 case _ => } } def f1(n: Any): Boolean = { n.isInstanceOf[Int] } def f2(n: Int): Int = { n + 1 } //Set any - > int [map] def f3(n: Any): Int = { n.asInstanceOf[Int] } }
Partial function quick start
Use partial function to solve the previous problem, [code demonstration + description]
object PartialFunDemo02 { def main(args: Array[String]): Unit = { //Using partial function to solve val list = List(1, 2, 3, 4, "hello") //Define a partial function //1. PartialFunction[Any,Int] indicates that the parameter type received by the partial function is Any and the return type is Int //2. isDefinedAt(x: Any) if it returns true, it will call apply to build an object instance. If it is false, it will be filtered //3. apply constructor, add + 1 to the passed in value and return (new set) val partialFun = new PartialFunction[Any,Int] { override def isDefinedAt(x: Any) = { println("x=" + x) x.isInstanceOf[Int] } override def apply(v1: Any) = { println("v1=" + v1) v1.asInstanceOf[Int] + 1 } } //Using partial function //Note: if partial function is used, map cannot be used and collect should be used //Explain the execution process of partial function //1. Traverse all elements of the list //2. then call val element = if(partialFun-isDefinedAt(list single element)) {partialFun-apply(list single element)} //3. For each element obtained, put it into a new set and finally return val list2 = list.collect(partialFun) println("list2" + list2) } }
Summary of partial function
Use to build the implementation class of idiosyncrasy (using the anonymous subclass of PartialFunction)
PartialFunction is a trait (see the source code)
When constructing a partial function, the parameter form [Any, Int] is generic. The first represents the parameter type and the second represents the return parameter
When partial functions are used, all elements of the collection will be traversed. When the compiler executes the process, it will execute isDefinedAt() first. If it is true, it will execute apply and build a new Int object to return
If isDefinedAt() is false, this element will be filtered out, that is, no new Int object will be built
The map function does not support partial functions, because the underlying mechanism of the map is all loop traversal, which cannot filter and process the elements of the original set
The collect function supports partial functions
Abbreviated form of partial function
object PartialFun03 { def main(args: Array[String]): Unit = { //The partial function of the previous case can be abbreviated def partialFun2: PartialFunction[Any,Int] = { //Abbreviated as case statement case i:Int => i + 1 case j:Double => (j * 2).toInt } val list = List(1, 2, 3, 4, 1.2, 2.4, 1.9f, "hello") val list2 = list.collect(partialFun2) println("list2=" + list2) //The second abbreviated form val list3 = list.collect{ case i:Int => i + 1 case j:Double => (j * 2).toInt case k:Float => (k * 3).toInt } println("list3=" + list3) } }
Operation results
list2=List(2, 3, 4, 5, 2, 4) list3=List(2, 3, 4, 5, 2, 4, 5)