实用技巧 List 1 2 3 4 5 6 7 List (1 , 9 , 2 , 4 , 5 ) span (_ < 3 ) List (1 , 9 , 2 , 4 , 5 ) partition (_ < 3 ) List (1 , 9 , 2 , 4 , 5 ) splitAt 2 List (1 , 9 , 2 , 4 , 5 ) groupBy (5 < _)
Iterator grouped 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import scala.collection.{AbstractIterator , mutable}import org.apache.spark.{SparkConf , SparkContext }import org.apache.spark.sql.SparkSession import org.apache.spark.sql.BigquerySparkSession ._val conf = new SparkConf ()val builder = SparkSession .builder().config(conf).enableHiveSupport()val spark = builder.getOrCreateBigquerySparkSession()val df = spark.sql("use db; select * from table" )val dataset = df.rdd.mapPartitions(iter => { iter.grouped(100 ) .flatMap(rows => { val records = new mutable.MutableList [String ]() rows.foreach(row => records.add(JSON .toJSONString(row, false ))) records }) }) val filteredEmptyLine = dataset .filter(_ != null ) .map(JSON .toJSONString(_, false )) .filter(_.trim.length != 0 )
Enum 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 scala> object Types extends Enumeration { | type Types = Value | val ZERO , ONE , TWO = Value | | def toType (types: String ): Option [Types ] = { | toUpperCase)).headOption | Types .values.find(_.toString.trim.toUpperCase.equals(types.trim.toUpp erCase)) | } | } defined object Types scala> Types .toType("Zero" ) res6: Option [Types .Types ] = Some (ZERO ) scala> Types .toType("ONE" ) res7: Option [Types .Types ] = Some (ONE ) scala> Types .toType("two" ) res8: Option [Types .Types ] = Some (TWO ) scala> Types .toType("three" ) res9: Option [Types .Types ] = None scala> Types .toType("THREE" ) res10: Option [Types .Types ] = None
Case class 和 class 的 8 个不同之处 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 scala> case class Person (name: String , age: Int ) defined class Person scala> val bj = Person ("Benedict Jin" , 18 ) bj: Person = Person (Benedict Jin ,18 ) scala> bj.name res0: String = Benedict Jin scala> bj.age res1: Integer = 18 scala> bj.toString res2: String = Person (Benedict Jin ,18 ) scala> bj.hashCode res3: Int = 1059149039 scala> Person ("Benedict Jin" , 18 ).hashCode res4: Int = 1059149039 scala> Person ("Benedict Jin" , 18 ) == bj res5: Boolean = true scala> import java.io._ import java.io._scala> val bos = new ByteArrayOutputStream bos: java.io.ByteArrayOutputStream = scala> val oos = new ObjectOutputStream (bos) oos: java.io.ObjectOutputStream = java.io.ObjectOutputStream @62 ddd21b scala> oos.writeObject(bj) scala> val obj = new ObjectInputStream (new ByteArrayInputStream (bos.toByteArray) ).readObject() obj: Object = Person (Benedict Jin ,18 ) scala> Person ("Benedict Jin" , 18 ) == obj res6: Boolean = true scala> bj match { | case Person ("Benedict Jin" , 18 ) => println("matched" ) | case _ => println("non-matched" ) | } matched scala> bj.productArity res7: Int = 2 scala> bj.productIterator.next() res8: Any = Benedict Jin scala> bj.productElement(1 ) res9: Any = 18 scala> bj.productPrefix res10: String = Person
打印 trait 中的字段 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 scala> trait T { | var t: String = "" | } defined trait T scala> case class Person (name: String ) extends Serializable with T defined class Person scala> Person ("Benedict Jin" ) res6: Person = Person (Benedict Jin ) scala> import scala.runtime.ScalaRunTime import scala.runtime.ScalaRunTime scala> case class Person2 (name: String ) extends Serializable with T { | override def toString : String = ScalaRunTime ._toString(this ) | } defined class Person2 scala> Person2 ("Benedict Jin" ).toString res7: String = Person2 (Benedict Jin ) scala> case class Person3 (name: String ) extends Serializable with T { | override def toString : String = s"Person3(${this.name} , ${this.t} )" | } defined class Person3 scala> val p3 = Person3 ("Benedict Jin" ) p3: Person3 = Person3 (Benedict Jin , ) scala> p3.t = "t" p3.t: String = t scala> p3.toString res8: String = Person3 (Benedict Jin , t)
单元测试 详见,《在不同场景下,如何选择合适的 JVM 语言 》
常见问题 classOf 和 getClass 的区别 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 scala> class A defined class A scala> val a = new A a: A = A @1 d483de4 scala> a.getClass res0: Class [_ <: A ] = class A scala> classOf[A ] res1: Class [A ] = class A scala> a.getClass == classOf[A ] res2: Boolean = true scala> val c: Class [A ] = a.getClass <console>:13 : error: type mismatch ; found : Class [?0 ] where type ?0 < : A required: Class [A ] Note : ?0 <: A , but Java -defined class Class is invariant in type T . You may wish to investigate a wildcard type such as `_ < : A `. (SLS 3.2 .10 ) val c:Class [A ] = a.getClass ^ scala> val c: Class [_ <: A ] = a.getClass c: Class [_ <: A ] = class A scala> c.getName res3: String = A scala> classOf[A ].getName res4: String = A
稳定的标识符模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 scala> def m (i: Int ) = { | val a = 3 | val b = 2 | val c = 1 | i match { | case `a` => 0 | case `b` => -1 | case `c` => 4 | case _ => 2 | } | } m: (i: Int )Int scala> m(1 ) res17: Int = 4 scala> m(2 ) res18: Int = -1 scala> m(3 ) res19: Int = 0
Tips: Full code is here and here .
在函数调用里面,对变量进行赋值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 scala> val map = new java.util.LinkedHashMap [String , String ]() map: java.util.LinkedHashMap [String ,String ] = {} scala> map.put("1" , "1" ) res0: String = null scala> map.put("2" , "2" ) res1: String = null scala> map.put("3" , "3" ) res2: String = null scala> map res3: java.util.LinkedHashMap [String ,String ] = {1 =1 , 2 =2 , 3 =3 } scala> var s = "1 " s: String = "1 " scala> map.containsValue(s) res4: Boolean = false scala> map.containsValue(s = s.trim) res5: Boolean = false scala> s res6: String = 1 scala> "1" .equals(s) res7: Boolean = true
Java 的 Lambda 表达式转为 Scala 的 Function Java 的 Lambda 表达式 1 final static ThreadLocal<String> BLOG_ID = ThreadLocal.withInitial(() -> "null" );
反面示例 1 2 3 4 5 6 7 8 9 10 11 12 13 private val BLOG_ID : ThreadLocal [String ] = ThreadLocal .withInitial(() -> "null" )val blogIdFunc: java.util.function.Supplier [String ] = () => "null" val func: java.util.function.Supplier [String ] = () => "null" error: type mismatch ; found : () => String required: java.util.function.Supplier [String ] val func: java.util.function.Supplier [String ] = () => "null" ^
正面示例 1 2 3 4 val blogIdFunc: java.util.function.Supplier [String ] = new Supplier [String ] { override def get (): String = "null" }private val BLOG_ID : ThreadLocal [String ] = ThreadLocal .withInitial(blogIdFunc)
补充 1 2 3 4 5 6 7 8 9 private val BLOG_ID : ThreadLocal [String ] = new ThreadLocal [String ]() { override def initialValue (): String = "null" }
Tips: Full code is here .
如何传递变长参数 描述 1 2 3 4 5 6 7 8 9 10 11 12 scala> def detail (d: Any *): Unit = println("%s_%s" .format(d)) detail: (d: Any *)Unit scala> detail("a" , "b" ) java.util.MissingFormatArgumentException : Format specifier '%s' at java.util.Formatter .format(Formatter .java:2519 ) at java.util.Formatter .format(Formatter .java:2455 ) at java.lang.String .format(String .java:2940 ) at scala.collection.immutable.StringLike $class .format(StringLike .scala:318 ) at scala.collection.immutable.StringOps .format(StringOps .scala:29 ) at .detail(<console>:11 ) ... 32 elided
解决 1 2 3 4 5 6 scala> def detail (d: Any *): Unit = println("%s_%s" .format(d: _*)) detail: (d: Any *)Unit scala> detail("a" , "b" ) a_b
补充 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def countSubString (str: String , sub: String ): Int = str.sliding(sub.length).count(slide => slide == sub)def patchSubString (str: String , sub: String ): String = str.patch(str.lastIndexOf(sub), "" , sub.length)def superFormat (str: String , detail: String *): String = { val holderSize: Int = countSubString(str, "%s" ) val detailSize: Int = detail.size var result: String = str if (detailSize < holderSize) { for (_ <- 0 until (holderSize - detailSize)) { result = patchSubString(result, "%s" ) } } result.format(detail: _*) }
Tips: Full code is here and here .
隐式转换 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 scala> import java.util import java.utilscala> val l = new util.LinkedList [String ]() l: java.util.LinkedList [String ] = [] scala> l.add("yuzhouwan.com" ) res0: Boolean = true scala> Seq (l) res1: Seq [java.util.LinkedList [String ]] = List ([yuzhouwan.com]) scala> l.toSeq <console>:14 : error: value toSeq is not a member of java.util.LinkedList [String ] l.toSeq ^ scala> import scala.collection.JavaConversions ._ import scala.collection.JavaConversions ._scala> l.toSeq res3: Seq [String ] = Buffer (yuzhouwan.com)
资料 Book
群名称
群号
人工智能(高级)
人工智能(进阶)
BigData
算法