未分类

前言RDD整体上分为Value类型和Key-Value类型Value类型map(func)作用:返回一个新的RDD,该RDD由每一个输入元素经过func函数转换后组成需求:创建一个1-10数组的RDD,将所有元素*2形成新的RDD创建RDDvalintRDD:RDD[Int]=sc.makeRDD(1to10)转换RDD方法转换重点是每一个数据valresRDD:RDD[Int]=intRDD.map(_*2)结果输出valr=resRDD.collect().mkString(",")println(r)----------2,4,6,8,10,12,14,16,18,20mapPartitions(func)作用:类似于map,但独立地在RDD的每一个分区上运行,因此func的函数类型必须是(Interator[T])=>Iterator[U]。效率要优于map()但分区数据太大容易造成内存溢出的错误(OOM)需求:创建一个1-10数组的RDD,将所有元素*2形成新的RDD创建RDDvalintRDD:RDD[Int]=sc.makeRDD(1to10)转换RDD方法转换重点是每一个分区,所以匿名函数``传入是可迭代类型,返回也要可迭代类型valresRDD:RDD[Int]=intRDD.mapPartitions((iter)=>{//这里的map()是Scala中的函数iter.map(i=>i*2)})结果输出valr=resRDD.collect().mkString(",")println(r)----------2,4,6,8,10,12,14,16,18,20mapPartitionsWithIndex(func)作用:类似于mapPartitions,但func带有一个整数参数表示所在分区的索引值,因此func的函数类型必须是(Int,Interator[T])=>Iterator[U];需求:创建一个RDD,使元素跟所在分区索引形成一个元组组成一个新的RDD创建RDDvalintRDD:RDD[Int]=sc.makeRDD(1to10)转换RDD方法转换重点是每一个分区valresRDD:RDD[(String,Int)]=intRDD.mapPartitionsWithIndex{//有多个传入参数时,一般使用casecase(num,datas)=>{datas.map(("分区"+num,_))}}结果输出valr=resRDD.collect().mkString(",")println(r)----------(分区1,1),(分区3,2),(分区4,3),(分区6,4),(分区7,5),(分区9,6),(分区11,7),(分区12,8),(分区14,9),(分区15,10)flatMap(func)作用:类似于Scala中的flatMap(),每一个输入元素可以被映射为0或多个输出元素(所以func应该返回一个序列,而不是单一元素)需求:创建一个Array数组中的List元素RDD,映射成Array数组RDD创建RDDvallistRDD:RDD[List[Int]]=sc.makeRDD(Array(List(1,2),List(3,4)))转换RDDvalresRDD:RDD[Int]=listRDD.flatMap(list=>list)结果输出valr=resRDD.collect().mkString(",")println(r)----------1,2,3,4glom()作用:将每一个分区形成一个数组,形成新的RDD类型是RDD[Array[T]]创建RDDvallistRDD:RDD[Int]=sc.makeRDD(1to10,3)转换RDDvalarrayRDD:RDD[Array[Int]]=listRDD.glom()结果输出分区不能平均存放数据时,多余的数据会往后面的分区存放valres=arrayRDD.collect()res.foreach(nums=>println(nums.mkString(",")))------------------------------------------------1,2,34,5,67,8,9,10groupBy()作用:分组,按照传入函数的返回值进行分组。将相同的key对应的值放入一个迭代器,返回一个元组:RDD[(Int,Iterable[Int])],前一个Int是传入函数返回值。需求:区分奇偶数创建RDDvallistRDD:RDD[Int]=sc.makeRDD(1to10)转换RDDvalresRDD:RDD[(Int,Iterable[Int])]=listRDD.groupBy(_%2)结果输出valr=resRDD.collect()r.foreach(println)------------------(0,CompactBuffer(2,4,6,8,10))(1,CompactBuffer(1,3,5,7,9))filter(func)作用:过滤。返回一个新的RDD,该RDD由经过func函数计算后返回值为true的输入元素组成。需求:过滤奇数,留下偶数创建RDDvallistRDD:RDD[Int]=sc.makeRDD(1to10)转换RDDvalresRDD:RDD[Int]=listRDD.filter(_%2==0)结果输出valr=resRDD.collect()println(r.mkString(","))------------------2,4,6,8,10sample(withReplacement,fraction,[seed])作用:数据抽样withReplacement:布尔值true:有放回的抽样,采用PoissonSampler抽样器(Poisson分布),false:无放回的抽样,采用BernoulliSampler的抽样器fraction:当为true时,这就是数学中的期望当为false时,这就是概率,值的范围[0,1]seed:随机数种子,不好把握,保持默认就好需求:创建一个RDD(1-10),从中选择不放回抽样创建RDDvallistRDD:RDD[Int]=sc.makeRDD(1to10)转换RDDvalresRDD:RDD[Int]=listRDD.sample(false,0.4)结果输出其实每次抽样结果的值和值的个数的个数都不一样,但会保持在一个数学算法的范围里valr=resRDD.collect()println(r.mkString(","))------------------------5,7,9,10distinct([numPartitions])作用:去重。因为去重之后,数据会减少,各个数据原本所在的分区会被洗牌打乱,所以其中就有shuffle操作,参数是去重后所产生的分区数量,可选。需求:去重,指定两个分区。创建RDDvallistRDD:RDD[Int]=sc.makeRDD(List(6,2,1,2,8,3,5,5,4,1,2,2))转换RDDvalresRDD:RDD[Int]=listRDD.distinct(2)结果输出如果不指定分区,输出的数据会自动排序valr=resRDD.collect()println(r.mkString(","))-----------------------4,6,8,2,1,3,5coalesce(numPartitions,[shuffle])作用:减少分区数。用于大数据集过滤后,提高小数据集的执行效率。参数如果大于原本的分区数,则分区数不变,默认false不进行shuffle操作。需求:减少分区数。创建RDDvallistRDD:RDD[Int]=sc.makeRDD(1to10,6)转换RDDvalnewPartition:RDD[Int]=listRDD.coalesce(3)结果输出如果不指定分区,输出的数据会自动排序println("原本的分区数:"+listRDD.partitions.size)println("新的分区数:"+newPartition.partitions.size)---------------------------------------------------原本的分区数:6新的分区数:3repartition(numPartitions:Int)作用:根据分区数,重新通过网络随机洗牌所有数据,分区数可以比原来多也可以少,一定会进行shuffle操作。通过源码发现,其实在底层也调用了coalesce()方法,并且shuffle=truedefrepartition(numPartitions:Int)(implicitord:Ordering[T]=null):RDD[T]=withScope{coalesce(numPartitions,shuffle=true)}sortBy(func,[ascending],[numPartitions])作用:使用func先对数据进行处理,按照处理后的数据比较结果排序,默认为升序。func:处理函数ascending:默认true升序,false降序numPartitions:处理后的分区数需求创建一个RDD,按照不同的规则,进行讲叙排序,并指定3个分区创建RDDvallistRDD:RDD[Int]=sc.makeRDD(List(5,8,2,4,6,9,1),8)转换RDDvalresRDD:RDD[Int]=listRDD.sortBy(x=>x,false,3)结果输出如果不指定分区,输出的数据会自动排序println("排序前分区数:"+listRDD.partitions.length)println("排序后分区数:"+resRDD.partitions.length)valr=resRDD.collect()println(r.mkString(","))-----------------------4,6,8,2,1,3,5排序前分区数:8排序后分区数:39,8,6,5,4,2,1

未分类

什么是RDDRDD(ResilientDistributedDataset)叫做分布式数据集,是Spark中最基本的数据抽象。代码中是一个抽象类,它代表一个不可变、可分区、里面的元素可并行计算的集合。RDD属性一组分区(Partition),即数据集的基本组成单位;一个计算每个分区的函数;RDD之间的依赖关系;一个Partitioner,即RDD的分片函数;一个列表,存储存取每个Partition的优先位置(preferredlocation)。RDD特点RDD表示只读的分区的数据集,对RDD进行改动,只能通过RDD的转换操作,由一个RDD得到一个新的RDD,新的RDD包含了从其他RDD衍生所必需的信息。RDDs之间存在依赖,RDD的执行是按照血缘关系延时计算的。如果血缘关系较长,可以通过持久化RDD来切断血缘关系。RDD分区分区详情查看RDD逻辑上是分区的,每个分区的数据是抽象存在的,计算的时候会通过一个compute函数得到每个分区的数据。如果RDD是通过已有的文件系统构建,则compute函数是读取指定文件系统中的数据,如果RDD是通过其他RDD转换而来,则compute函数是执行转换逻辑将其他RDD的数据进行转换。RDD的创建RDD的创建又三种方式:从集合中创建RDD;从外部存储创建RDD;从其他RDD创建。创建RDD,首先要构建Spakr的上下文对象//创建Spark上下文对像valconf:SparkConf=newSparkConf().setMaster("local[*]").setAppName("mkRdd")valsc:SparkContext=newSparkContext(config=conf)集合中创建这种方式又叫从内存创建,Spark主要提供了两种函数:parallelize和makeRDD,查看源码会发现makeRDD底层把数据传给了parallelize,所以这两个是差不多参数传入有序,可重复集合valstrRDD:RDD[String]=sc.makeRDD(Array("1","2","3","4"))valintRDD:RDD[Int]=sc.parallelize(List(1,2,3,4))外部创建路径支持本地文件、HDFS路径,和支持HDFS文件的URL,比如HBasevalfileRDD:RDD[String]=sc.textFile("路径")其他RDD创建RDD使用算子计算后返回的还是RDD

2020-2-13 1104 0
未分类

前言RDD的分区概念在RDD概述里已经说过,这里就不在复述分区分区数越多,任务数越多,执行效率就高makeRDD()分区的体现使用数组创建RDD,直接保存,我们发现数组里只有5的元素,但却输出的8个文件。查看makeRDD()的源码,发现还有第二个参数numSlices这个第二个参数,就是指定切为多少分区。defmakeRDD[T:ClassTag](seq:Seq[T],//注意这里是numSlices,因为textFile()方法有点不一样numSlices:Int=defaultParallelism):RDD[T]=withScope{parallelize(seq,numSlices)}它的默认值(defaultParallelism)是会去判定你是否设置(conf),否者就去获取全部的CPU个数来进行默认设置。overridedefdefaultParallelism():Int={conf.getInt("spark.default.parallelism",math.max(totalCoreCount.get(),2))}textFile()分区的体现同样的保存只产生了两个查看textFile()的源码,第二个参数是minPartitions(最小的)其中调用了hadoopFile(),所以Spark对文件的切分规则跟Hadoop是一样的,(所以就会出现一个指定分区为2,但实际却有3的情况,因为分2个,还会剩下,所以就会产生大于2个)。所以当自定义了分区数,实际情况可能不是这个数deftextFile(path:String,minPartitions:Int=defaultMinPartitions):RDD[String]=withScope{assertNotStopped()hadoopFile(path,classOf[TextInputFormat],classOf[LongWritable],classOf[Text],minPartitions).map(pair=>pair._2.toString).setName(path)}继续向下看源码,发现首先获取了配置里参数,然后与2作比较,取小的作为默认参数defdefaultMinPartitions:Int=math.min(defaultParallelism,2)

2020-2-13 1002 0
未分类

概述Spark的三种运行方式Local模式:直接解压,就可以运行Yarn模式:需要配置HadoopYarnStandalone模式:Spark独立运行模式Spark安装机器数需启动的进程所属者Local1无SparkStandalone多台Master及WorkerSparkYarn1Yarn及HDFSHadoop配置构建一个由Master+n个Slave构成的Spark集群,Spark运行在集群中。配置Worker运行节点在Spakr的conf/复制模板cpslaves.templateslavesslaves文件是指定Worker运行的机器//如果只有一台机器,这个文件就不用改//如果是配置集群模式,就把原本的localhost改成各个机器名masterslave1slave2配置Master运行端口在Spark的conf/目录下复制模板cpspark-env.sh.templatespark-env.sh修改Spark-env.sh//添加上SPARK_MASTER_HOST=masterSPARK_MASTER_PORT=7077//如果产生了notsetJAVA_HOME的错误,就加上JAVA_HOMEexportJAVA_HOME=/usr/java/jdk1.8.0_221//修改完记得source分发配置的单机器就不用分发启动启动命令在sbin/目录下[root@mastersbin]#./start-all.shstartingorg.apache.spark.deploy.master.Master,loggingto/usr/local/src/spark/spark-2.0.0/logs/spark-root-org.apache.spark.deploy.master.Master-1-master.outlocalhost:startingorg.apache.spark.deploy.worker.Worker,loggingto/usr/local/src/spark/spark-2.0.0/logs/spark-root-org.apache.spark.deploy.worker.Worker-1-master.out[root@mastersbin]#jps5863Worker5927Jps5688Master运行测试bin/spark-submit\--classorg.apache.spark.examples.SparkPi\./examples/jars/spark-examples_2.11-2.0.0.jar\100

未分类

概述Spark可以直接连接Yarn,不需要额外构建Spark集群。有yarn-client和yarn-cluster两种模式,主要区别在于:Driver程序的运行节点。yarn-client:Driver程序运行在客户端,适用于交互、调试,希望立即看到app的输出yarn-cluster(集群):Driver程序运行在RM(ResourceManager)启动的AP(APPmaster)适用于生成环境。配置修改hadoop配置文件yarn-site.xml,添加如下内容<!--是否启动一个线程检查每个任务正使用的物理内存量,如果任务超出分配值,则直接将其杀掉,默认是true--><property><name>yarn.nodemanager.pmem-check-enabled</name><value>false</value></property><!--是否启动一个线程检查每个任务正使用的虚拟内存量,如果任务超出分配值,则直接将其杀掉,默认是true--><property><name>yarn.nodemanager.vmem-check-enabled</name><value>false</value></property>修改Spark/conf下的spark-env.sh,添加Hadoop的etc/hadoop,修改完记得sourceYARN_CONF_DIR=/usr/local/src/hadoop/hadoop-2.6.0/etc/hadoop配置集群就分发,不是集群就不用分发//分发spark-env.shscpspark-env.shslave1:/usr/local/src/spark/spark-2.0.0-bin-hadoop2.6/conf/scpspark-env.shslave2:/usr/local/src/spark/spark-2.0.0-bin-hadoop2.6/conf///分发yarn-site.xmlscpyarn-site.xmlslave1:/usr/local/src/hadoop/hadoop-2.6.0/etc/hadoop/scpyarn-site.xmlslave2:/usr/local/src/hadoop/hadoop-2.6.0/etc/hadoop/提交一个例子测试(注意启动Hadoop和Yarn)bin/spark-submit\--classorg.apache.spark.examples.SparkPi\--masteryarn\--deploy-modeclient\./examples/jars/spark-examples_2.11-2.0.0.jar\100日志查看因为在Spark计算,Yarn调度资源,Yarn不能获取到Spark的执行日志,所以需要配置一下修改配置文件Spark/conf下的spark-defaults.conf如下首先创建好存放目录hadoopfs-mkdir/historyserverforSparkpark.yarn.historyServer.address=master:18080spark.history.ui.port=18080spark.eventLog.enabled=truespark.eventLog.dir=hdfs://master:9000/historyserverforSparkspark.history.fs.logDirectory=hdfs://master:9000/historyserverforSpark重启spark历史服务//关闭sbin/stop-history-server.sh//开启sbin/start-history-server.sh提交任务到Yarn执行bin/spark-submit\--classorg.apache.spark.examples.SparkPi\--masteryarn\--deploy-modeclient\./examples/jars/spark-examples_2.11-2.0.0.jar\100Web页面查看日志

2020-2-13 896 0
未分类

搭建前的准备搭建Scala环境首先需要你的IDEA需要搭建好Scala的环境(可以参考这篇)还需要一个和Hadoop的Windows版二进制文件下载地址:http://public-repo-1.hortonworks.com/hdp-win-alpha/winutils.exe搭建配置winutils创建一个目录E:\winutils\bin把winutils.exe放进去配置环境变量//新建变量变量名:HADOOP_HOME变量值:E:\winutils//把新建变量加入Path%HADOOP%\bin这样就安装好了配置IDEA在IDEA配置好Scala后,就只需要在pom.xml文件里添加Spark依赖就好pom.xml文件<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.bigdataboy</groupId><artifactId>SparkDemo</artifactId><version>1.0</version><dependencies><!--Spark依赖--><!--https://mvnrepository.com/artifact/org.apache.spark/spark-core--><dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_2.11</artifactId><version>2.0.0</version></dependency></dependencies></project>等待依赖下载完成Spark案例第一个Spark案例,单词统计统计数据helloScalahelloJavahelloPython统计代码defmain(args:Array[String]):Unit={//设定Spark运行环境valconf:SparkConf=newSparkConf().setMaster("local[*]").setAppName("wc")//创建Spark上下文连接对象valsc=newSparkContext(conf)//读取文件,一行数据为一个元素vallines:RDD[String]=sc.textFile("./src/main/Scala/data.txt")//空格分隔,使其扁平化valwords:RDD[String]=lines.flatMap(_.split(""))//格式化数据,方便统计valwordToOne:RDD[(String,Int)]=words.map((_,1))//聚合valwordToSum:RDD[(String,Int)]=wordToOne.reduceByKey(_+_)//收集并打印结果println(wordToSum.collect().mkString(","))//保存结果wordToSum.saveAsTextFile("./src/main/Scala/out")}

2020-2-7 846 1
未分类

计算类声明一个集合vallistInt:List[Int]=List(1,2,3,4,5)最大值maxprintln("Max="+listInt.max)-------------------------------Max=5最小值minprintln("Min="+listInt.min)-------------------------------Min=1乘积productprintln("product="+listInt.product)--------------------------------------product=120排序创建一个集合vallistStr:List[String]=List("21","22","33","11","aa")vallistInt:List[Int]=List(1,2,3,4,5)sortBy()按照某个标准排序,参数传入一个函数按照大小排序valvalue2:List[Int]=listInt.sortBy(x=>x)println(value2.mkString(","))-----------------------------1,2,3,4,5按照个位的大小排序valvalue3:List[String]=listStr.sortBy((s)=>s.substring(1,2))println(value3.mkString(","))-----------------------------21,11,22,33,aasortWith()指定排序规则创建集合vallistInt:List[Int]=List(1,2,3,4,5)vallistStr1:List[String]=List("21","22","33","11")大小排序把>改成<就是升序valvalue4:List[Int]=listInt.sortWith((left,right)=>{left>right//左边的大于右边的降序})println(value4.mkString(","))-----------------------------5,4,3,2,1按照个位排序valvalue5:List[String]=listStr1.sortWith((left,right)=>{left.substring(1,2).toInt<right.substring(1,2).toInt})println(value5.mkString(","))-----------------------------21,11,22,33结构类对集合中的每个元素进行操作,每个元素的结构映射(变换)集合反转创建集合vallistInt:List[Int]=List(1,2,3,4,5)反转valreverse:List[Int]=listInt.reverseprintln(reverse.mkString(","))------------------------------5,4,3,2,1groupBy()分组,传入函数是需要指定Key值,会返回一个(K,List()),(K1,List()),..,这的Map集合创建集合vallistStr:List[String]=List("21","22","33","11","aa")按照自身分组privatevalvalue:Map[String,List[String]]=listStr.groupBy((x)=>{x})value.foreach(println)----------------------(11,List(11))(33,List(33))(22,List(22))(21,List(21))(aa,List(aa))按照首位数字分组valvalue1:Map[String,List[String]]=listStr.groupBy(x=>x.substring(0,1))value1.foreach(println)-----------------------(a,List(aa))(1,List(11))(2,List(21,22))(3,List(33))map()映射,元素结构转换创建集合vallistStr2=List("a","a","c","c","b","a")把每个元素转换成(元素,1)valvalue6:List[(String,Int)]=listStr2.map((x)=>(x,1))println(value6.mkString(","))-----------------------------(a,1),(a,1),(c,1),(c,1),(b,1),(a,1)偏平化创建集合vallistStr3=List("HelloScala","HelloPython","HelloJava")扁平化valvalue9:List[String]=listStr3.flatMap(x=>x.split(""))println(listStr3.mkString(","))println(value9.mkString(","))-------------------------------HelloScala,HelloPython,HelloJavaHello,Scala,Hello,Python,Hello,Java如果集合里的元素不太规律,就需要把进行判断处理vallistAny:List[Any]=List(1,List(2,3),List(4,5),66)valvalue12:List[Any]=listAny.flatMap((Any)=>{if(Any.isInstanceOf[List[Int]]){Any.asInstanceOf[List[Int]]//转换成可迭代的类型}else{List(Any)}})println(value12)------------------------------List(1,2,3,4,5,66)过滤判断为True的留下,False的去掉valListToInt:List[Int]=List(1,2,3,4)过滤大于2的数valvalue10:List[Int]=ListToInt.filter(x=>x>2)println(value10.mkString(","))------------------------------3,4zip创建集合valListToInt:List[Int]=List(1,2,3,4)valListToInt1:List[Int]=List(2,3,4,5)zip操作valvalue11:List[(Int,Int)]=ListToInt.zip(ListToInt1)println(value11.mkString(","))------------------------------(1,2),(2,3),(3,4),(4,5)其他(待补充)reduce()会对集合元素进行两两操作,最后得出一个值创建一个集合vallistInt:List[Int]=List(1,2,3,4,5)实现集合相加,跟sum()一样vali:Int=listInt.reduce((right,left)=>{right+left})println(i)----------15//实际逻辑((((1+2)+3)+4)+5)+6

2020-2-5 743 0
未分类

集合分类Scala集合分为两大类可变(mutable)和不可变(immutable)不可变:数组声明好,数组的长度就不能再改变可变:数组声明好,可就改变数组的长度三大集合Seq集合有序可重复代表List()不可变的List()默认无需导入创建vallist:List[Int]=List(1,2,3,4)修改内容list.updated(1,11)//通过索引修改查,遍历//查,取值list(索引)//遍历list.foreach(println)for(l<-list){println(l)}可变ListBuffer()需要导入创建集合varlistBuffer:ListBuffer[Int]=ListBuffer(1,2,3,4)增加元素listBuffer.insert(1,11)//索引插入listBuffer.append(1)//加在最后删除元素listBuffer.remove(1)//通过索引删值listBuffer.remove(1,2)//索引,几个listBuffer.drop(2)//从索引0开始删几个修改元素listBuffer.update(0,11)//通过索引修改元素查询,遍历元素//查询,取值listBuffer(索引)//遍历listBuffer.foreach(println)for(l<-listBuffer){println(l)}特殊的List()集合空集合println(List())//List()println(Nil)//List()用处1::2::NilSet集合无序不可重复使用Set集合需要记住,无序(就表示需要索引的操作不能用)主要使用是生成新的集合,本身变化不大创建Set集合//默认是不可变的valset:Set[Int]=Set(1,2,1,2,3,4)//可变Set集合valmSet:mutable.Set[Int]=mutable.Set(1,2,3,44,5,5,5,1,2)一些操作//添加删除varmSet1:mutable.Set[Int]=mSet+11println(mSet1.mkString(","))varmSet2:mutable.Set[Int]=mSet-1println(mSet2.mkString(","))---------------------------------------1,2,3,5,11,442,3,5,44Map集合无序,(k->v),key不能重复,value可重复。创建//创建不可变valmap:Map[String,Int]=Map("a"->1,"b"->2)//创建可变valmMap:mutable.Map[String,Int]=mutable.Map("aa"->1,"bb"->2,"cc"->3)增加valmap1:Map[String,Int]=map+("c"->3)println(map1.mkString(","))-------------------------------------------a->1,b->2,c->3修改valmap2:Map[String,Any]=map.updated("a","11")println(map2.mkString(","))//可变Map可以这样改mMap("aa")=11println(mMap.mkString(","))//还可以通过添加覆盖的思想修改valmap4:Map[String,Any]=map+("a"->"22")println(map4.mkString(","))---------------------------------------------------a->11,b->2aa->11,bb->2,cc->3a->22,b->2健取值vali:Int=map("a")println(i)---------------------1删除valmap3:Map[String,Int]=map-"a"println(map3.mkString(","))--------------------------------------b->2

2020-2-4 905 0
未分类

引言Scala数组分为两大类可变(mutable)和不可变(immutable)Array()数组介绍Array为不可变数组不可变是指内存地址不变,一但确定,数组的长度不能变创建valints:Array[Int]=Array(1,2,3,4,5)数组取值注意是()ints(0)修改元素updata(索引,新值)//按照索引修改ints.update(1,10)//updata(索引,新值)添加元素不可变数组添加元素是指添加后产生新的数组,并不是在原数组添加//注意连接的符号valints1=ints:+12println(ints1.mkString(","))----------------------------1,2,3,4,5,12valints2=15+:intsprintln(ints2.mkString(","))----------------------------12,1,2,3,4,5遍历数组使用for循环遍历for(elem<-ints){println(elem)}使用方法foreach(函数)函数返回值要是Unit函数接收的参数就是数组的元素//下面是简化过程ints.foreach((i:Int)=>{println(i)})ints.foreach(println(_))ints.foreach(println)ArrayBuffer()介绍ArrayBuffer()为可变数组创建valarrayBuffer:ArrayBuffer[String]=ArrayBuffer("a","b","c","d")添加元素insert(索引,新元素)插入元素arrayBuffer.insert(1,"B")println(arrayBuffer.mkString(","))----------------------------------a,B,b,c,d+=组合元素+==组合数组arrayBuffer+="e"println(arrayBuffer.mkString(",")---------------------------------a,b,c,d,earrayBuffer++=Array("a","zz")println(arrayBuffer.mkString(",")---------------------------------a,b,c,d,e,a,zz删除元素使用索引删除arrayBuffer.remove(1)//索引删除arrayBuffer.remove(1,2)//从索引开始删几个arrayBuffer-=1删除数组中的指定元素数组中没有找到也不会报错arrayBuffer--=Array("a")修改元素arrayBuffer(0)="A"查看元素//通过索引获取println(arrayBuffer(0))遍历数组//函数arrayBuffer.foreach(println(_))//for循环for(buffer<-arrayBuffer){println(buffer)}数组可变性的转换可变转不可变toArrayvalarray:Array[String]=arrayBuffer.toArray不可变转可变toBuffervalbuffer1:mutable.Buffer[Int]=ints.toBuffer

2020-2-4 830 0