Spark笔记:复杂RDD的API的理解(下)

本篇接着谈谈那些稍微复杂的API。

1)   flatMapValues:针对Pair RDD中的每个值应用一个返回迭代器的函数,然后对返回的每个元素都生成一个对应原键的键值对记录

  这个方法我最开始接触时候,总是感觉很诧异,不是太理解,现在回想起来主要原因是我接触的第一个flatMapValues的例子是这样的,代码如下:

1

2

3

4

val rddPair: RDD[(String, Int)] = sc.parallelize(List(("x01"2), ("x02"5), ("x03"8), ("x04"3), ("x01"12), ("x03"9)), 1)

val rddFlatMapVals1:RDD[(String,Int)] = rddPair.flatMapValues { x => x to (6) }

/* 结果:(x01,2),(x01,3),(x01,4),(x01,5),(x01,6),(x02,5),(x02,6),(x04,3),(x04,4),(x04,5),(x04,6) */

println("====flatMapValues 1====:" + rddFlatMapVals1.collect().mkString(","))

  这个实例使用的是scala里Range这种数据类型,Range数据类型是一个数字的范围,细细讲它的理论也没啥意思,我们看下面的例子吧,代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

val list:List[Int] = List(1,2,3,4,5,6)

val len:Int = list.size - 1

val r:Range = 0 to len

 

for (ind <- r){

  print(list(ind) + ";")// 1;2;3;4;5;6;

}

 println("")

for (ind <- 0 to len){

  print(list(ind) + ";")// 1;2;3;4;5;6;

}

println(""

  由以上代码我们可以看到0 to 3就是指代0,1,2,3这三个数字,所以我们可以在for循环里指代这个范围。

  其实flatMapValues接受的外部方法的返回类型是一个Seq类型,Seq类型在scala里就是一个序列,一个有序的序列,我们可以把他理解成数组,我们来看看下面的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

def flatMapRange(par:Int):Range = {

  par to 6

}

 

def flatMapList(par:Int):List[Int] = {

  List(par + 1000)

}

 

def flatMapSeq(par:Int):Seq[Int] = {

  Seq(par + 6000)

}

  val rddFlatMapVals2:RDD[(String,Int)] = rddPair.flatMapValues { x => flatMapRange(x) }

  /* 结果:(x01,2),(x01,3),(x01,4),(x01,5),(x01,6),(x02,5),(x02,6),(x04,3),(x04,4),(x04,5),(x04,6) */

  println("====flatMapValues 2====:" + rddFlatMapVals2.collect().mkString(","))

  val rddFlatMapVals3:RDD[(String,Int)] = rddPair.flatMapValues { x => flatMapList(x) }

  /* 结果:(x01,1002),(x02,1005),(x03,1008),(x04,1003),(x01,1012),(x03,1009) */

  println("====flatMapValues 3====:" + rddFlatMapVals3.collect().mkString(","))

  val rddFlatMapVals4:RDD[(String,Int)] = rddPair.flatMapValues { x => flatMapSeq(x) }

  /* 结果:(x01,6002),(x02,6005),(x03,6008),(x04,6003),(x01,6012),(x03,6009) */

  println("====flatMapValues 4====:" + rddFlatMapVals4.collect().mkString(","))

  谈到flatMapValues这个方法,让我不得不回忆起另外一个与之类似的方法flatMap,我们来看看这个方法的实例吧,代码如下:

1

2

3

4

5

6

7

8

9

val rddFlatMap1:RDD[(String,Int)] = rddPair.flatMap(x => List((x._1,x._2 3000)))

 // 结果:(x01,3002),(x02,3005),(x03,3008),(x04,3003),(x01,3012),(x03,3009)

 println("=====flatMap 1======:" + rddFlatMap1.collect().mkString(","))

 val rddFlatMap2:RDD[Int] = rddPair.flatMap(x => List(x._2 8000))

 // 结果:8002,8005,8008,8003,8012,8009

 println("=====flatMap 2======:" + rddFlatMap2.collect().mkString(","))

 val rddFlatMap3:RDD[String] = rddPair.flatMap(x => List(x._1 "@!@" + x._2))

 // 结果:x01@!@2,x02@!@5,x03@!@8,x04@!@3,x01@!@12,x03@!@9

println("=====flatMap 3======:" + rddFlatMap3.collect().mkString(","))

 由此可见flatMap方法里的参数也是一个Seq,而且他们之间可以相互替代使用,只不过flatMapValues是让二元组里的第一个元素保持不变的情况下进行计算的(及key值不发生变化)。不过spark不会无缘无故的定义一个flatMapValues,它其实和spark里的分区紧密相关,关于spark的分区知识我会在后面文章里谈谈的。

2) rightOuterJoin,leftOuterJoin,rddCogroup及右连接,左连接和分组函数

    我们首先看看他们的使用吧,代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

val rdd:RDD[(String,Int)] = sc.makeRDD(List(("x01",2),("x02",5),("x03",9),("x03",21),("x04",76)))

val other:RDD[(String,Int)] = sc.makeRDD(List(("x01",4),("x02",6),("x03",11)))

 

val rddRight:RDD[(String,(Option[Int],Int))] = rdd.rightOuterJoin(other)

/* 结果:(x02,(Some(5),6)),(x03,(Some(9),11)),(x03,(Some(21),11)),(x01,(Some(2),4)) */

println("====rightOuterJoin====:" + rddRight.collect().mkString(","))

 

val rddLeft:RDD[(String,(Int,Option[Int]))] = rdd.leftOuterJoin(other)

/* 结果: (x02,(5,Some(6))),(x04,(76,None)),(x03,(9,Some(11))),(x03,(21,Some(11))),(x01,(2,Some(4))) */

println("====leftOuterJoin====:" + rddLeft.collect().mkString(","))

val rddSome = rddLeft.filter(x => x._2._2.isEmpty == false)// 过滤掉None的记录

/* 结果: (x02,(5,Some(6))),(x03,(9,Some(11))),(x03,(21,Some(11))),(x01,(2,Some(4)))*/

println("====rddSome===:" + rddSome.collect().mkString(","))

 

val rddCogroup: RDD[(String, (Iterable[Int], Iterable[Int]))] = rdd.cogroup(other)

/* 结果: (x02,(CompactBuffer(5),CompactBuffer(6))),(x04,(CompactBuffer(76),CompactBuffer())),(x03,(CompactBuffer(9, 21),CompactBuffer(11))),(x01,(CompactBuffer(2),CompactBuffer(4)))*/

println("===cogroup====:" + rddCogroup.collect().mkString(","))

  这三个方法很好理解,就和关系数据库里的左右连接,分组一样,不过它们的返回值在我刚学习spark时候很是疑惑了半天,这里就好好说下它们的返回值,这其实就是学习下scala的数据类型了。

  首先是Some数据类型,Some并不是一个直接操作的数据类型,它属于Option这个数据结构的,其实None也是Option里的数据结构,Some里面只能放一个元素,例如Some(1),Some((1,2)),为什么scala里还要这么繁琐的定义一个Option,并在其中还定义一个Some和一个None的结构呢?我们首先看看下面代码:

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

def optionSome():Unit = {

    /*

     * =======option for 1=========

      0:3

      2:8

      3:11

      =======option for 1=========

      =======option for 2=========

      0:3

      1:None

      2:8

      3:11

      =======option for 2=========

     */

    val list:List[Option[Int]] = List(Some(3),None,Some(8),Some(11))

    println("=======option for 1=========")

    for (i <- 0 until list.size){

      if (!list(i).isEmpty){

        println(i + ":" + list(i).get)

      }

    }

    println("=======option for 1=========")

    println("=======option for 2=========")

    for (j <- 0 until list.size){

      val res = list(j) match {       

        case None => println(j + ":None")

        case _ => println(j + ":" + list(j).get)

      }

    }

    println("=======option for 2=========")

  }

 

  Option数据结构其实想要表达的是一个数据集合,这个数据集合里要么有值,要么没值,这点在左右连接查询里就非常有用,其实左右连接最后的结果就是要么关联上了要么没有关联上。

  分组cogroup返回的结构是CompactBuffer,CompactBuffer并不是scala里定义的数据结构,而是spark里的数据结构,它继承自一个迭代器和序列,所以它的返回值是一个很容易进行循环遍历的集合,这点很符合cogroup的返回值类型。

好了,这篇内容就写完了,下一篇文章我将要简单聊聊spark分区,后面应该暂时会停停spark的学习,要搞搞前端的一些技术,这都是因为工作需要了。

  最后我将完整示例代码给大家分享下,代码如下:

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

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

package cn.com.sparktest

 

import org.apache.spark.SparkConf

import org.apache.spark.SparkContext

import org.apache.spark.SparkContext._

import org.apache.spark.rdd.RDD

import scala.collection.immutable.List

import org.apache.spark.util.collection.CompactBuffer

 

object ScalaTest {

  val conf: SparkConf = new SparkConf().setAppName("spark scala").setMaster("local[2]")

  val sc: SparkContext = new SparkContext(conf)

 

  def aggrFtnOne(par: ((Int, Int), Int)): (Int, Int) = {

    /*

       *aggregate的初始值为(0,0):

        ====aggrFtnOne Param===:((0,0),1)

                ====aggrFtnOne Param===:((1,1),2)

                ====aggrFtnOne Param===:((3,2),3)

                ====aggrFtnOne Param===:((6,3),4)

                ====aggrFtnOne Param===:((10,4),5)*/

    /*

       *aggregate的初始值为(1,1):

        ====aggrFtnOne Param===:((1,1),1)

        ====aggrFtnOne Param===:((2,2),2)

        ====aggrFtnOne Param===:((4,3),3)

        ====aggrFtnOne Param===:((7,4),4)

        ====aggrFtnOne Param===:((11,5),5)

       * */

    println("====aggrFtnOne Param===:" + par.toString())

    val ret: (Int, Int) = (par._1._1 + par._2, par._1._2 1)

    ret

  }

 

  def aggrFtnTwo(par: ((Int, Int), (Int, Int))): (Int, Int) = {

    /*aggregate的初始值为(0,0):::::((0,0),(15,5))*/

    /*aggregate的初始值为(1,1):::::((1,1),(16,6))*/

    println("====aggrFtnTwo Param===:" + par.toString())

    val ret: (Int, Int) = (par._1._1 + par._2._1, par._1._2 + par._2._2)

    ret

  }

 

  def foldFtn(par: (Int, Int)): Int = {

    /*fold初始值为0:

        =====foldFtn Param====:(0,1)

        =====foldFtn Param====:(1,2)

        =====foldFtn Param====:(3,3)

        =====foldFtn Param====:(6,4)

        =====foldFtn Param====:(10,5)

        =====foldFtn Param====:(0,15)

       * */

    /*

       * fold初始值为1:

        =====foldFtn Param====:(1,1)

        =====foldFtn Param====:(2,2)

        =====foldFtn Param====:(4,3)

        =====foldFtn Param====:(7,4)

        =====foldFtn Param====:(11,5)

        =====foldFtn Param====:(1,16)

       * */

    println("=====foldFtn Param====:" + par.toString())

    val ret: Int = par._1 + par._2

    ret

  }

   

  def reduceFtn(par:(Int,Int)):Int = {

    /*

     * ======reduceFtn Param=====:1:2

             ======reduceFtn Param=====:3:3

       ======reduceFtn Param=====:6:4

       ======reduceFtn Param=====:10:5

     */

    println("======reduceFtn Param=====:" + par._1 ":" + par._2)

    par._1 + par._2

  }

 

  def sparkRDDHandle(): Unit = {

    val rddInt: RDD[Int] = sc.parallelize(List(12345), 1)

 

    val rddAggr1: (Int, Int) = rddInt.aggregate((00))((x, y) => (x._1 + y, x._2 1), (x, y) => (x._1 + y._1, x._2 + y._2))

    println("====aggregate 1====:" + rddAggr1.toString()) // (15,5)

 

    val rddAggr2: (Int, Int) = rddInt.aggregate((00))((x, y) => aggrFtnOne(x, y), (x, y) => aggrFtnTwo(x, y)) // 参数可以省略元组的括号

    println("====aggregate 2====:" + rddAggr2.toString()) // (15,5)

 

    val rddAggr3: (Int, Int) = rddInt.aggregate((11))((x, y) => aggrFtnOne((x, y)), (x, y) => aggrFtnTwo((x, y))) // 参数使用元组的括号

    println("====aggregate 3====:" + rddAggr3.toString()) // (17,7)

     

    val rddAggr4: (Int, Int) = rddInt.aggregate((10))((x, y) => (x._1 * y, x._2 1), (x, y) => (x._1 * y._1, x._2 + y._2))

    println("====aggregate 4====:" + rddAggr4.toString()) // (120,5)  

 

    val rddFold1: Int = rddInt.fold(0)((x, y) => x + y)

    println("====fold 1====:" + rddFold1// 15

 

    val rddFold2: Int = rddInt.fold(0)((x, y) => foldFtn(x, y)) // 参数可以省略元组的括号

    println("====fold 2=====:" + rddFold2// 15

 

    val rddFold3: Int = rddInt.fold(1)((x, y) => foldFtn((x, y))) // 参数使用元组的括号

    println("====fold 3====:" + rddFold3// 17

     

    val rddReduce1:Int = rddInt.reduce((x,y) => x + y)

    println("====rddReduce 1====:" + rddReduce1)// 15

     

    val rddReduce2:Int = rddInt.reduce((x,y) => reduceFtn(x,y))

    println("====rddReduce 2====:" + rddReduce2)// 15

     

  }

   

  def combineFtnOne(par:Int):(Int,Int) = {

    /*

     * ====combineFtnOne Param====:2

       ====combineFtnOne Param====:5

       ====combineFtnOne Param====:8

       ====combineFtnOne Param====:3

     */

    println("====combineFtnOne Param====:" + par)

    val ret:(Int,Int) = (par,1)

    ret

  }

   

  def combineFtnTwo(par:((Int,Int),Int)):(Int,Int) = {

    /*

      ====combineFtnTwo Param====:((2,1),12)

      ====combineFtnTwo Param====:((8,1),9)

     * */

    println("====combineFtnTwo Param====:" + par.toString())

    val ret:(Int,Int) = (par._1._1 + par._2,par._1._2 1)

    ret

  }

   

  def combineFtnThree(par:((Int,Int),(Int,Int))):(Int,Int) = {

    /*

     * 无结果打印

     */

    println("@@@@@@@@@@@@@@@@@@")

    println("====combineFtnThree Param===:" + par.toString())

    val ret:(Int,Int) = (par._1._1 + par._2._1,par._1._2 + par._2._2)

    ret

  }

   

  def flatMapRange(par:Int):Range = {

    par to 6

  }

   

  def flatMapList(par:Int):List[Int] = {

    List(par + 1000)

  }

   

  def flatMapSeq(par:Int):Seq[Int] = {

    Seq(par + 6000)

  }

 

  def sparkPairRDD(): Unit = {

    val rddPair: RDD[(String, Int)] = sc.parallelize(List(("x01"2), ("x02"5), ("x03"8), ("x04"3), ("x01"12), ("x03"9)), 1)

     

    /* def combineByKey[C](createCombiner: Int => C, mergeValue: (C, Int) => C, mergeCombiners: (C, C) => C): RDD[(String, C)] */   

    val rddCombine1:RDD[(String,(Int,Int))] = rddPair.combineByKey(x => (x, 1), (com: (Int, Int), x) => (com._1 + x, com._2 1), (com1: (Int, Int), com2: (Int, Int)) => (com1._1 + com2._1, com1._2 + com2._2))

    println("====combineByKey 1====:" + rddCombine1.collect().mkString(",")) // (x02,(5,1)),(x03,(17,2)),(x01,(14,2)),(x04,(3,1))

     

    val rddCombine2:RDD[(String,(Int,Int))] = rddPair.combineByKey(x => combineFtnOne(x), (com: (Int, Int), x) => combineFtnTwo(com,x), (com1: (Int, Int), com2: (Int, Int)) => combineFtnThree(com1,com2))

    println("=====combineByKey 2====:" + rddCombine2.collect().mkString(",")) // (x02,(5,1)),(x03,(17,2)),(x01,(14,2)),(x04,(3,1))

     

     

    val rddKeys:RDD[String] = rddPair.keys

    /*结果:x01,x02,x03,x04,x01,x03  注意调用keys方法时候不能加上括号,否则会报错*/

    println("====keys====:" + rddKeys.collect().mkString(","))

     

    val rddVals:RDD[Int] = rddPair.values

    /*结果:2,5,8,3,12,9  注意调用values方法时候不能加上括号,否则会报错*/

    println("=====values=====:" + rddVals.collect().mkString(","))

     

    val rddFlatMapVals1:RDD[(String,Int)] = rddPair.flatMapValues { x => x to (6) }

    /* 结果:(x01,2),(x01,3),(x01,4),(x01,5),(x01,6),(x02,5),(x02,6),(x04,3),(x04,4),(x04,5),(x04,6) */

    println("====flatMapValues 1====:" + rddFlatMapVals1.collect().mkString(","))

    val rddFlatMapVals2:RDD[(String,Int)] = rddPair.flatMapValues { x => flatMapRange(x) }

    /* 结果:(x01,2),(x01,3),(x01,4),(x01,5),(x01,6),(x02,5),(x02,6),(x04,3),(x04,4),(x04,5),(x04,6) */

    println("====flatMapValues 2====:" + rddFlatMapVals2.collect().mkString(","))

    val rddFlatMapVals3:RDD[(String,Int)] = rddPair.flatMapValues { x => flatMapList(x) }

    /* 结果:(x01,1002),(x02,1005),(x03,1008),(x04,1003),(x01,1012),(x03,1009) */

    println("====flatMapValues 3====:" + rddFlatMapVals3.collect().mkString(","))

    val rddFlatMapVals4:RDD[(String,Int)] = rddPair.flatMapValues { x => flatMapSeq(x) }

    /* 结果:(x01,6002),(x02,6005),(x03,6008),(x04,6003),(x01,6012),(x03,6009) */

    println("====flatMapValues 4====:" + rddFlatMapVals4.collect().mkString(","))

     

    val rddFlatMap1:RDD[(String,Int)] = rddPair.flatMap(x => List((x._1,x._2 3000)))

    // 结果:(x01,3002),(x02,3005),(x03,3008),(x04,3003),(x01,3012),(x03,3009)

    println("=====flatMap 1======:" + rddFlatMap1.collect().mkString(","))

    val rddFlatMap2:RDD[Int] = rddPair.flatMap(x => List(x._2 8000))

    // 结果:8002,8005,8008,8003,8012,8009

    println("=====flatMap 2======:" + rddFlatMap2.collect().mkString(","))

    val rddFlatMap3:RDD[String] = rddPair.flatMap(x => List(x._1 "@!@" + x._2))

    // 结果:x01@!@2,x02@!@5,x03@!@8,x04@!@3,x01@!@12,x03@!@9

    println("=====flatMap 3======:" + rddFlatMap3.collect().mkString(","))

  }

   

  def optionSome():Unit = {

    /*

     * =======option for 1=========

      0:3

      2:8

      3:11

      =======option for 1=========

      =======option for 2=========

      0:3

      1:None

      2:8

      3:11

      =======option for 2=========

     */

    val list:List[Option[Int]] = List(Some(3),None,Some(8),Some(11))

    println("=======option for 1=========")

    for (i <- 0 until list.size){

      if (!list(i).isEmpty){

        println(i + ":" + list(i).get)

      }

    }

    println("=======option for 1=========")

    println("=======option for 2=========")

    for (j <- 0 until list.size){

      val res = list(j) match {       

        case None => println(j + ":None")

        case _ => println(j + ":" + list(j).get)

      }

    }

    println("=======option for 2=========")

  }

   

  def pairRDDJoinGroup():Unit = {

    val rdd:RDD[(String,Int)] = sc.makeRDD(List(("x01",2),("x02",5),("x03",9),("x03",21),("x04",76)))

    val other:RDD[(String,Int)] = sc.makeRDD(List(("x01",4),("x02",6),("x03",11)))

     

    val rddRight:RDD[(String,(Option[Int],Int))] = rdd.rightOuterJoin(other)

    /* 结果:(x02,(Some(5),6)),(x03,(Some(9),11)),(x03,(Some(21),11)),(x01,(Some(2),4)) */

    println("====rightOuterJoin====:" + rddRight.collect().mkString(","))

     

    val rddLeft:RDD[(String,(Int,Option[Int]))] = rdd.leftOuterJoin(other)

    /* 结果: (x02,(5,Some(6))),(x04,(76,None)),(x03,(9,Some(11))),(x03,(21,Some(11))),(x01,(2,Some(4))) */

    println("====leftOuterJoin====:" + rddLeft.collect().mkString(","))

    val rddSome = rddLeft.filter(x => x._2._2.isEmpty == false)// 过滤掉None的记录

    /* 结果: (x02,(5,Some(6))),(x03,(9,Some(11))),(x03,(21,Some(11))),(x01,(2,Some(4)))*/

    println("====rddSome===:" + rddSome.collect().mkString(","))

     

    val rddCogroup: RDD[(String, (Iterable[Int], Iterable[Int]))] = rdd.cogroup(other)

    /* 结果: (x02,(CompactBuffer(5),CompactBuffer(6))),(x04,(CompactBuffer(76),CompactBuffer())),(x03,(CompactBuffer(9, 21),CompactBuffer(11))),(x01,(CompactBuffer(2),CompactBuffer(4)))*/

    println("===cogroup====:" + rddCogroup.collect().mkString(","))

  }

   

  def scalaBasic(){

    val its:Iterable[Int] = Iterable(1,2,3,4,5)

    its.foreach { x => print(x + ",") }// 1,2,3,4,5,

     

    val tuple2Param1:Tuple2[String,Int] = Tuple2("x01",12)// 标准定义二元组

    val tuple2Param2:(String,Int) = ("x02",29)// 字面量定义二元组

     

    /* 结果: x01:12*/

    println("====tuple2Param1====:" + tuple2Param1._1 ":" + tuple2Param1._2)

    /* 结果: x02:29 */

    println("====tuple2Param2====:" + tuple2Param2._1 ":" + tuple2Param2._2)

     

    val tuple6Param1:Tuple6[String,Int,Int,Int,Int,String] = Tuple6("xx01",1,2,3,4,"x1x")// 标准定义6元组

    val tuple6Param2:(String,Int,Int,Int,Int,String) = ("xx02",1,2,3,4,"x2x")// 字面量定义6元组

     

    /* 结果: xx01:1:2:3:4:x1x */

    println("====tuple6Param1====:" + tuple6Param1._1 ":" + tuple6Param1._2 ":" + tuple6Param1._3 ":" + tuple6Param1._4 ":" + tuple6Param1._5 ":" + tuple6Param1._6)

    /* 结果: xx02:1:2:3:4:x2x */

    println("====tuple6Param2====:" + tuple6Param2._1 ":" + tuple6Param2._2 ":" + tuple6Param2._3 ":" + tuple6Param2._4 ":" + tuple6Param2._5 ":" + tuple6Param2._6)

     

     val list:List[Int] = List(1,2,3,4,5,6)

     val len:Int = list.size - 1

     val r:Range = 0 to len

      

     for (ind <- r){

       print(list(ind) + ";")// 1;2;3;4;5;6;

     }

      println("")

     for (ind <- 0 to len){

       print(list(ind) + ";")// 1;2;3;4;5;6;

     }

     println("")

  }

 

  def main(args: Array[String]): Unit = {

    scalaBasic()

    optionSome()

     

    sparkRDDHandle()

    sparkPairRDD()

    pairRDDJoinGroup()  

 

     

  }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值