Scala学习——核心概念

面向对象编程——类
在scala中定义一个类,类中有一个成员变量age。系统默认会生成一个无参的主构造器
成员变量的getter和setter方法 getter方法就叫age,setter方法叫age_
1、   定义不带 private var  字段, 此时 scala 生成的面向 JVM 的类时, 会定义为 private name 字段, 并提供 public getter setter 方法
2、  而如果使用 private 修饰字段, 则生成的 getter setter 也是 private
3、如果定义 val  字段, 则只会生成 getter 方法,因为常量值不可更改,所以没有setter方法
4、如果不希望生成 setter getter 方法, 则将字段声明为 private[this]
private修饰的myAge可以被类的当前对象和类的其他对象访问。但是由private[this]修饰的myAge不会生成getter和setter方法,只能被类的当前对象访问而不能被类的其他对象访问
辅助constructor
Scala 中, 可以给类定义多个辅助 constructor , 类似于 Java 中的构造函数重载
辅助 constructor 之间可以互相调用, 而且必须第一行调用主 constructor 
主构造器与类同名,他的参数可以放在类名后面,在类中,如果某些代码不在任何方法中,或者不在代码块中,那么这些代码就会被默认为主构造器的代码
面向对象编程——对象
object相当于class的单个实例。在第一次调用object的方法时,就会执行object的constructor
object不能定义有参的constructor。object的constructor只会在第一次被调用时执行一次
伴生对象、伴生类
如果有一个class和一个与class同名的object,那么就称这个object是这个类的伴生对象,这个类就是这个object的伴生类
1、必须放在同一个scala文件中。
2、伴生类与伴生对象之间可以互相访问private成员
在类中调用伴生对象的方法,直接通过伴生对象.方法名调用
在伴生对象中调用类的方法,可以通过创建一个伴生类的对象来调用伴生类中的方法
apply方法
object 中非常重要的一个特殊方法, 就是 apply 方法
通常在伴生对象中实现 apply 方法, 并在其中实现构造伴生类的对象的功能
而创建伴生类的对象时, 通常不会使用 new Class 的方式, 而是使用 Class() 的方式, 隐式地调
用伴生对象的
apply 方法, 这样会让对象创建更加简洁  
isinstanceOf和asinstanceOf
用object来实现枚举功能
如果要实现枚举, 则需要用 object 继承 Enumeration 类, 并且调用 Value 方法 来初始化枚举值 
还可以通过 Value 传入枚举值的 id name , 通过 id toString 可以获取; 还可以通过 id name 来查找枚举值
main方法
scala中的main方法必须定义在object中。Object类相当于java中的静态类
除了写main方法之外,还可以通过继承App这个trait,实现和main相同的功能
object也可以extends抽象类,并重写抽象类中的方法,使用关键字override
面向对象编程——继承
Scala中的继承和Java中一样,也使用extends关键字
子类重写父类的方法,使用关键字override
子类调用父类中已被子类重写的方法,使用关键字super
不仅仅是方法可以被override 定义为val的常量也可以在子类中override,并给赋予新的值

类型转换和类型判断
在scala中,使用isInstanceOf来判断是否为子类  a.isInstanceOf[B] 判断对象a是否为B类型或者B类的子类型
使用asInstanceOf来完成类型转换 如果a是B类型或者B的子类型,就可以安全地把a赋给B类型的对象b b=a.asInstanceOf(B)
通过对象.getClass()方法可以获得该对象所属的类classOf[类名]可以精准地获得类

访问修饰符
private、private[this]、protect、protect[this]
如果使用 protected[this] , 则只能在当前子类对象中访问父类的字段和方法, 无法通过其他子类对象访问父类的
字段和方法
如果使用 protected[this] , 则只能在当前类对象中访问类的字段和方法, 无法通过该类的对象访问

面向对象编程——trait
trait可以作为接口来使用,但是不适用implements 而是使用extends
scala 不支持对类进行多继承, 但是 支持多重继承 trait ,  使用 with 关键字即可
trait中可自定义字段和方法(抽象方法和抽象方法均可) 
如果是在类中实现trait中的抽象方法,不用关键字override
trait中也可以定义字段,如果一个类extends了这个trait,name这个类就自动获得了这个字段,可以在类中直接使用,
就像是自己内部声明的一样

混入trait
在创建类的对象时, 指定该对象混入某个 trait , 这样, 就只有这个对象混入该 trait 的方法, 而类的其他对象则有。
此时,混入的trait如果有和该类继承的trait相同的方法,将会覆盖本身的方法

trait调用链
要形成trait调用链,必须满足以下三个条件:
1、调用链必须是一个类继承多个trait
2、多个trait中必须包含同一个方法,并且多个trait有一个共同的父trait
3、调用的多个trait的同一个方法中,最后的语句必须是super.方法名,通过这种形式调用trait调用链中的下一个trait方法
满足以上条件才能构成trait调用链,在调用链中按照从右往左的顺序依次调用同一个方法。  

trait的构造机制
继承了 trait 的类的构造机制如下:
1 、 父类的构造函数执行,类本身的构造器最后执行;
2 、  trait 的构造代码执行, 多个 trait 从左到右依次执行;
3 、 构造 trait 时会先构造父 trait , 如果多个 trait 继承同一个父 trait , 则父 trait 只会构造一次;
4 、 所有 trait 构造完毕之后, 子类的构造函数执行  

trait也可以继承类
Scala 中,  trait 也可以继承自 class , 此时这个 class 就会成为所有继承该 trait 的类的父类  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 批量操作是指一次性对多个数据进行操作,可以提高操作效率。在使用 Spark 读写 HBase 时,也可以使用批量操作来提高效率。具体实现方式如下: 1. 批量写入数据 使用 HBase 的 Put 类来创建要写入的数据,然后将 Put 对象添加到一个 List 中,最后使用 HBase 的 Table 类的 put 方法来批量写入数据。示例代码如下: ```scala val conf = HBaseConfiguration.create() val connection = ConnectionFactory.createConnection(conf) val table = connection.getTable(TableName.valueOf("table_name")) val puts = new ListBuffer[Put]() for (i <- 1 to 100) { val put = new Put(Bytes.toBytes(s"row_$i")) put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("col"), Bytes.toBytes(s"value_$i")) puts += put } table.put(puts.toList.asJava) ``` 2. 批量读取数据 使用 HBase 的 Get 类来创建要读取的数据,然后将 Get 对象添加到一个 List 中,最后使用 HBase 的 Table 类的 get 方法来批量读取数据。示例代码如下: ```scala val conf = HBaseConfiguration.create() val connection = ConnectionFactory.createConnection(conf) val table = connection.getTable(TableName.valueOf("table_name")) val gets = new ListBuffer[Get]() for (i <- 1 to 100) { val get = new Get(Bytes.toBytes(s"row_$i")) get.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("col")) gets += get } val results = table.get(gets.toList.asJava) for (result <- results) { val row = Bytes.toString(result.getRow) val value = Bytes.toString(result.getValue(Bytes.toBytes("cf"), Bytes.toBytes("col"))) println(s"$row: $value") } ``` 以上就是使用 Scala 实现 Spark 读写 HBase 的批量操作的方法。 ### 回答2: 在实际的数据处理中,一次需要对多条数据进行读写操作,如果每次都进行单条的读写逐条操作会使程序效率非常低下。所以spark提供了批量操作API,可以对多条数据进行一次性的读写操作,极大地提高了程序的效率。 批量读操作: 批量读取数据的方式有两种:Get和Scan。 使用Get方式读取多条数据,需要将每条数据对应的Get对象添加到List集合当中,再将List集合转换为RDD对象进行操作。示例代码如下: ```scala val conf = HBaseConfiguration.create() conf.set(TableInputFormat.INPUT_TABLE, tableName) val gets = new util.ArrayList[Get]() gets.add(new Get(Bytes.toBytes("rowkey1"))) gets.add(new Get(Bytes.toBytes("rowkey2"))) gets.add(new Get(Bytes.toBytes("rowkey3"))) conf.set(TableInputFormat.SCAN, convertScanToString(new Scan())) val getRdd = sc.parallelize(gets) val hbaseRdd = getRdd.map((_, null)).hbaseBulkGet(conf, tableName, (result: Result) => { val kv: Array[Byte] = result.getValue(Bytes.toBytes(family), Bytes.toBytes(column)) Bytes.toString(kv) }) println(hbaseRdd.collect.toBuffer) ``` 使用Scan方式读取多条数据,需要将Scan对象作为参数传入,再将RDD对象转换为PairRDD并使用hbaseScan方法进行操作。示例代码如下: ```scala val conf = HBaseConfiguration.create() conf.set(TableInputFormat.INPUT_TABLE, tableName) val scan = new Scan(Bytes.toBytes("rowkey1"), Bytes.toBytes("rowkey3")) conf.set(TableInputFormat.SCAN, convertScanToString(scan)) val hbaseRdd = sc.hbaseScanRDD(conf).map((result: Result) => { val kv: Array[Byte] = result.getValue(Bytes.toBytes(family), Bytes.toBytes(column)) Bytes.toString(kv) }) println(hbaseRdd.collect.toBuffer) ``` 批量写操作: 批量写操作可以使用Put对象集合,将多条数据对应的Put对象添加到集合中,并将集合转换成RDD进行操作即可。示例代码如下: ```scala val conf = HBaseConfiguration.create() conf.set(TableOutputFormat.OUTPUT_TABLE, tableName) val puts = new util.ArrayList[Put]() puts.add(new Put(Bytes.toBytes("rowkey1")).addColumn(Bytes.toBytes(family), Bytes.toBytes(column), Bytes.toBytes("value1"))) puts.add(new Put(Bytes.toBytes("rowkey2")).addColumn(Bytes.toBytes(family), Bytes.toBytes(column), Bytes.toBytes("value2"))) puts.add(new Put(Bytes.toBytes("rowkey3")).addColumn(Bytes.toBytes(family), Bytes.toBytes(column), Bytes.toBytes("value3"))) val putRdd = sc.parallelize(puts) putRdd.hbaseBulkPut(conf, tableName) ``` 总结: 批量操作是Spark访问HBase的常见操作方式,在实际的实现过程中需要注意以下几点: 1、Get和Scan对象在HBase中读取数据的方式不一样,需要注意区分; 2、使用批量读操作可以大大提高程序效率,减少读写操作的时间消耗; 3、使用批量写操作需要合理规划写入的数据,避免出现数据冲突问题,影响程序的运行。 ### 回答3: 本篇文章将继续深入介绍如何使用Scala编码实现Spark读写操作HBase,具体涉及到HBase的批量操作。 一、Batch操作概述 在使用HBase进行数据处理的时候,我们常常需要对一个或多个表进行批量操作,批量操作即是针对 HBase的多行进行插入、删除等操作,以此来实现在HBase操作上的高效处理。HBase提供了很多批量操作API,比如 Put、Get、Delete、Scan,这些API都是可以批量操作的。 在Spark中,我们同样可以使用类似的API对HBase进行批量操作。本文将根据具体需求使用Spark实现HBase的批量操作。 二、批量操作的实现 Spark读写HBase时,使用RDD中的foreachPartition来对每个分区进行处理,在该函数内使用HBase API进行操作。关于批量操作,我们可以在每个分区中开启一个batch操作,将每个操作加入batch后,再提交即可。 例如,我们可以考虑实现一个批量put的功能,将RDD中的数据一批一批写入表中: ``` def insert(tableName: String, rdd: RDD[(String, String)]): Unit = { try{ rdd.foreachPartition({ iter => val conf = HBaseUtils.getHBaseConfiguration() conf.set(TableOutputFormat.OUTPUT_TABLE, tableName) val conn = ConnectionFactory.createConnection(conf) val table = conn.getTable(TableName.valueOf(tableName)) val puts = new java.util.ArrayList[Put]() iter.foreach { case (rowKey:String, value: String) => { // 构造put对象并append val put = new Put(Bytes.toBytes(rowKey)) put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnQualifier), Bytes.toBytes(value)) puts.add(put) if (puts.size() >= batchSize) { // 多条记录组成的put对象,使用put(List<Put>)一次性写入 table.put(puts) puts.clear() } } } // 如果puts还有内容,再写一次 if (puts.size() > 0) { table.put(puts) puts.clear() } table.close() conn.close() }) } catch { case e: Exception => e.printStackTrace() } } ``` 在该方法中,我们使用foreachPartition遍历RDD中的每个分区,然后通过Connection来获取HBase表实例。 之后定义了一个用于存放Put的List,当List的大小大于等于batchSize时,就将这个List中的所有put操作提交给HBase执行。 最后,释放资源,并为大家展示如何调用这个方法: ``` val rdd: RDD[(String, String)] = ... val tableName: String = ... insert(tableName, rdd) ``` 使用这种方式实现批量put,我们可以将一批数据提交到HBase执行,从而提升写入效率。当然,对于其他批量操作也可以应用类似的方式。 三、总结 本文根据实际需求,结合Spark和HBase的特点,实现了一些常用的批量操作,为大家提供了一个快速、高效的HBase操作方案。批量操作的好处是,可以将多条记录一次性操作,请求与写入等待时间都会得到缩短,获得更高的效率。感兴趣的同学可以试试,在实际开发中应该会受益匪浅!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值