【转载】Java基本类型的Writable封装

2023-05-16

Java基本类型的Writable封装

目前Java基本类型对应的Writable封装如表所示

屏幕快照 2016-03-08 上午10.44.07

所有这些Writable类都继承自WritableComparable。也就是说,它们是可比较的。

同时,它们都有get()set()方法,用于获得设置封装的值。

对整形(intlong)进行编码的时候,有固定长度格式IntWritableLongWritable)和可变长度格式VIntWritableVLongWritable)两种选择。

固定长度格式的整形,序列化后的数据是定长的,而可变长度格式则是用一种比较灵活的编码方式,对于数之比较小的整形,它们往往比较节省空间

同时,由于VIntwritableVLongWritable的编码规则是一样的,所以VIntwritable的输出可以用VLongWritable读入。

下面以VLongWritable为例,说明WritableJava基本类封装实现。

代码如下:

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
public class VIntWritable implements WritableComparable & lt ; VIntWritable & gt ; {
   private int value ;
 
   public VIntWritable ( ) { }
 
   public VIntWritable ( int value ) { set ( value ) ; }
 
   /** 设置VIntWritable的值. */
   public void set ( int value ) { this . value = value ; }
 
   /** 获取VIntWritable的值. */
   public int get ( ) { return value ; }
 
   @ Override
   public void readFields ( DataInput in ) throws IOException {
     value = WritableUtils . readVInt ( in ) ;
   }
 
   @ Override
   public void write ( DataOutput out ) throws IOException {
     WritableUtils . writeVInt ( out , value ) ;
   }
 
   /** Returns true iff <code>o</code> is a VIntWritable with the same value. */
   @ Override
   public boolean equals ( Object o ) {
     if ( ! ( o instanceof VIntWritable ) )
       return false ;
     VIntWritable other = ( VIntWritable ) o ;
     return this . value == other . value ;
   }
 
   @ Override
   public int hashCode ( ) {
     return value ;
   }
 
   /** Compares two VIntWritables. */
   @ Override
   public int compareTo ( VIntWritable o ) {
     int thisValue = this . value ;
     int thatValue = o . value ;
     return ( thisValue & lt ; thatValue ? - 1 : ( thisValue == thatValue ? 0 : 1 ) ) ;
   }
  
   @ Override
   public String toString ( ) {
     return Integer . toString ( value ) ;
   }
 
}
 

首先,每个Java基本类型Writale封装,其类的内部都包含一个对应基本类型的成员变量valueget()set()方法就是用来对该变量进行取值/赋值操作的。

Writable接口要求的readFields()write()方法,VIntWritable则是通过调用Writable工具类中提供的readVInt()writeVInt()读/写数据。方法readVInt()writeVInt()的实现也只是简单调用了readVLong()writeVLong(),所以,通过writeVInt()写的数据自然可以通过readVLong()读入。

读:

1
2
3
4
5
6
7
8
   public static int readVInt ( DataInput stream ) throws IOException {
     long n = readVLong ( stream ) ;
     if ( ( n & gt ; Integer . MAX_VALUE ) || ( n & lt ; Integer . MIN_VALUE ) ) {
       throw new IOException ( & quot ; value too long to fit in integer & quot ; ) ;
     }
     return ( int ) n ;
   }
 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   public static long readVLong ( DataInput stream ) throws IOException {
     byte firstByte = stream . readByte ( ) ;
     int len = decodeVIntSize ( firstByte ) ;
     if ( len == 1 ) {
       return firstByte ;
     }
     long i = 0 ;
     for ( int idx = 0 ; idx & lt ; len - 1 ; idx ++ ) {
       byte b = stream . readByte ( ) ;
       i = i & lt ; & lt ; 8 ;
       i = i | ( b & amp ; 0xFF ) ;
     }
     return ( isNegativeVInt ( firstByte ) ? ( i ^ - 1L ) : i ) ;
   }
 

1
2
3
4
5
6
7
8
9
   public static int decodeVIntSize ( byte value ) {
     if ( value & gt ; = - 112 ) {
       return 1 ;
     } else if ( value & lt ; - 120 ) {
       return - 119 - value ;
     }
     return - 111 - value ;
   }
 


写:

1
2
3
4
   public static void writeVInt ( DataOutput stream , int i ) throws IOException {
     writeVLong ( stream , i ) ;
   }
 

writeVLong()方法实现了对整形数值的变长编码,它的编码规则如下:

如果输入的整数大于或等于-112同时小于或等于127,那么编码需要1字节

否则,序列化结果的第一个字节,保存了输入整数的符号和后续编码的字节数。

符号和后续字节数依据下面的编码规则(又一个规则):

  • 如果是正数,则编码值范围落在-113-120间(闭区间),后续字节数可以通过-(v+112)计算。
  • 如果是负数,则编码值范围落在-121-128间(闭区间),后续字节数可以通过-(v+120)计算。

后续编码将高位在前,写入输入的整数(除去前面全0字节)。代码如下:

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
   public static void writeVInt ( DataOutput stream , int i ) throws IOException {
     writeVLong ( stream , i ) ;
   }
  
   /**
   * Serializes a long to a binary stream with zero-compressed encoding.
   * For -112 <= i <= 127, only one byte is used with the actual value.
   * For other values of i, the first byte value indicates whether the
   * long is positive or negative, and the number of bytes that follow.
   * If the first byte value v is between -113 and -120, the following long
   * is positive, with number of bytes that follow are -(v+112).
   * If the first byte value v is between -121 and -128, the following long
   * is negative, with number of bytes that follow are -(v+120). Bytes are
   * stored in the high-non-zero-byte-first order.
   *
   * @param stream 保存序列化结果输出流
   * @param i 被序列化的整数
   * @throws java.io.IOException
   */
   public static void writeVLong ( DataOutput stream , long i ) throws IOException {
//    处于[-112,127]的整数
     if ( i & gt ; = - 112 & amp ; & amp ; i & lt ; = 127 ) {
       stream . writeByte ( ( byte ) i ) ;
       return ;
     }
//      计算情况2的第一个字节
     int len = - 112 ;
     if ( i & lt ; 0 ) {
       i ^= - 1L ; // take one's complement'
       len = - 120 ;
     }
      
     long tmp = i ;
     while ( tmp != 0 ) {
       tmp = tmp & gt ; & gt ; 8 ;
       len -- ;
     }
      
     stream . writeByte ( ( byte ) len ) ;
      
     len = ( len & lt ; - 120 ) ? - ( len + 120 ) : - ( len + 112 ) ;
//      输出后续字节
     for ( int idx = len ; idx != 0 ; idx -- ) {
       int shiftbits = ( idx - 1 ) * 8 ;
       long mask = 0xFFL & lt ; & lt ; shiftbits ;
       stream . writeByte ( ( byte ) ( ( i & amp ; mask ) & gt ; & gt ; shiftbits ) ) ;
     }
   }
 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【转载】Java基本类型的Writable封装 的相关文章

随机推荐

  • 2. 安装GNOME和KDE图形化桌面

    安装GNOME和KDE图形化桌面 1 使用CD DVD介质配置本地Yum源2 安装GNOME图形化桌面2 1 安装GNOME xff1a 2 2 设置在系统启动时进入图形化桌面3 安装KDE图形化桌面3 1 安装KDE xff1a 3 2
  • 复位电路的几种设计

    本人转自 xff1a http hi baidu com yinweini2 item 48ba4f12f54587711009b591 复位源是导致单片机内部复位操作的源泉 xff0c 大致可分为七种 xff1a 上电复位 xff08 P
  • Hadoop入门经典:WordCount

    以下程序在hadoop1 2 1上测试成功 本例先将源代码呈现 xff0c 然后详细说明执行步骤 xff0c 最后对源代码及执行过程进行分析 一 源代码 package org jediael hadoopdemo wordcount im
  • Jlink 采用 SWD 模式下载电路接法

    在Jlink上 xff1a 对应的电路图为 xff1a 其中要使用的是 Pin1 gt vcc Pin7 gt SWDIO Pin9 gt SWCLK Pin4 gt GND 其他GND 引脚也可 在对于的开发板 xff08 举例 xff1
  • ubuntu系统硬盘温度过高的解决方法

    一 更改swap分区设置 在ubuntu 里面 xff0c swappiness的值的大小对如何使用swap分区是有着很大的联系的 swappiness 61 0的时候表示最大限度使用物理内存 xff0c 然后才是 swap空间 xff0c
  • MBus协议详解(一)

    看了许多关于MBus协议的资料 xff0c 感觉说的不具体 不完整 也不系统 xff0c 本人准备结合一个具体的产品实现 xff0c 从理论和实现上对MBus协议做一个详细的论述 xff0c 如有不当之处 xff0c 欢迎讨论 1 介绍 M
  • MBus协议详解(二)

    4 4 slave 设计 传输特性 xff1a slaves 被设计为具有两种不同恒定 sink 电流 xff0c 因此在总线上电压有 1V 的变化的时候 xff0c sink 电流的变化一定不能超过 0 2 为了传输一个 Mark xff
  • 多个进程对同一文件写入的问题

    转载 讨论关于并发环境下 xff0c 多个进程对同一文件写入的问题 xff0c 我们会涉及到文件共享的知识 在开始之前 xff0c 我们先讨论一些有关文件共享的知识 1 文件共享 Unix系统支持在不同进程间共享打开的文件 为此 xff0c
  • Linux内核里的DebugFS

    DebugFS xff0c 顾名思义 xff0c 是一种用于内核调试的虚拟文件系统 xff0c 内核开发者通过debugfs和用户空间交换数据 类似的虚拟文件系统还有procfs和sysfs等 xff0c 这几种虚拟文件系统都并不实际存储在
  • linux 只获取dns服务器地址

    有一款设备需要使用静态ip xff0c 但是还要用到dns解析域名 我的想法是定时去查看 etc resolve conf文件 xff0c 如果为空 xff0c 则获取一次dns 在嵌入式linux中 xff0c 我们使用busybox的u
  • linux更新文件

    最近发现很多同学不知道线上操作替换文件的要点 所以又整理了一下 线上替换一个正在运行进程的文件时 xff08 包括二进制 动态库 需要读取的资源文件等 xff09 应避免使用cp scp操作 而需要使用mv rsync作为替代 原因 xff
  • 大型网站架构与自动化运维——ISCSI安装配置

    ISCSI安装配置 一 存储简述 1 DAS xff1a 即直连方式存储 xff0c 英文全称是Direct Attached Storage 直接附加存储 顾名思义 xff0c 在这种方式中 xff0c 存储设备是通过电缆 xff08 通
  • Homebrew brew安装报错:Failed to connect to raw.githubusercontent.com port 443: Operation timed out

    报错 xff1a Failed to connect to raw githubusercontent com port 443 Operation timed out 解决方案 liukeruideMacBook Pro liukerui
  • 正则表达式中(?:)、(?=)以及(?!)等的用法

    out 61 re findall r 39 d 43 61 abc 39 34 1abc 34 只抽取数字 xff0c 并且该数字后面跟的字符是 34 abc 34 print out out1 61 re findall r 39 d
  • Oracle 12C rman备份的坑,搞不好就会hang死

    RMAN Backup to Platform Temporarily Creates DMP File in ORACLE HOME dbs 文档 ID 2349921 1 This has been reported as BUG 25
  • Linux 上安装配置 VNC Server

    一 简介 VNC Virtual Network Console xff0c 即 虚拟网络控制台 它是一款优秀的远程控制工具软件 xff0c 而且是基于 UNIX 和 Linux 操作系统的免费开源的 1 优点 远程控制能力强大 xff0c
  • Xshell能ping通但连不上CentOS 7

    转 xff1a https blog csdn net trackle400 article details 52755571 在虚拟机 xff08 Vmware Workstation xff09 下 xff0c 安装了CentOS7 x
  • Pandas RuntimeWarning: More than 20 figures have been opened. Figures created plt.close()也不起作用

    以下是源代码 xff0c 结果 xff1a function里有个for循环 xff0c 在每一次循环都有plt close xff0c 但是还是报错 xff1a More than 20 figures have been opened
  • 为企业提供存储功能的Red Hat Stratis 2.0.1发布了

    导读Red Hat的Stratis存储项目用于在Linux上提供企业存储功能 xff0c 以与ZFS和Btrfs之类的产品竞争 xff0c 同时在LVM和XFS之上构建 xff0c 这是其2020年守护进程的首次更新 通过Stratis x
  • 【转载】Java基本类型的Writable封装

    Java基本类型的Writable封装 目前Java基本类型对应的Writable封装如表所示 所有这些Writable类都继承自WritableComparable 也就是说 xff0c 它们是可比较的 同时 xff0c 它们都有get