在我多年的开发经验中,经常发现的一个情况就是,很多项目的对象字段或者是数据库字段本来是数字类型的,却被定义成字符串类型,这无关痛痒吗?

对于小项目来说,可能没什么影响,反正只要业务逻辑正确即可,性能没什么问题,因为数据也不多,用户也不多。

然而,对于大数据处理来说,这个可不是小事,从字符串替换为数字类型,可以极大地节省内存、磁盘存储以及网络带宽,减少IO的代价,而且很多数据结构和算法使用数字类型比字符串要更快。

我们来看一个例子,假设你有很多的日志需要处理,而每条日志都有一个唯一的标识,标识类似这样的格式:

F5051582611729507844
3832154813577306424
F1624235934976711017
3810376634214027595
F6884923813121317381
7278044081826528150

看到这些标识,你怎么想?我的第一反应应该是数字,可是怎么有个F呢?我想可以把它当做16进制。后来发现可以把F当做负号,这就是一个64位的长整型。

那么如果你把这些标识当成字符串,会有什么不同呢?

当然有,如果你每秒要处理这样的日志百万或者千万条,每条处理结果可能会包含百万或者千万个这样的标识元素构成的集合,这个不同就会体现的非常明显。

下面,我们来分析一下标识3832154813577306424的存储占用情况:

1、内存占用

当做字符串:我们知道,JAVA中字符串是由字符构成的,一个字符是由2个字节构成的(这是JAVA的悲剧了),上述标识有19个字符,所以,占用的内存大小为:19*2+4=42(字节),+4是因为字符串使用一个整型保存字符串的哈希值。

当做数字:如当做长整型,则占用的内存大小为8字节。

这里有5倍以上的差距了吧。

2、序列化字节大小

当我们需要通过网络传输这些标识或者需要把这些标识存储到磁盘中的时候,我们就需要把这些标识转换为字节数组,如何转换为字节数组呢?我们可以使用多种编码方式。

当做字符串:我们知道,JAVA中字符串转换为字节数组可以使用多种编码方式,我们看看常见的编码方式对如上字符串编码之后的字节数:

String abc = "3832154813577306424";System.out.println("3832154813577306424 length:"+abc.length());
System.out.println(Charset.defaultCharset().name()+":"+abc.getBytes().length);
System.out.println("unicode:"+abc.getBytes("unicode").length);
System.out.println("gbk:"+abc.getBytes("gbk").length);
System.out.println("gb2312:"+abc.getBytes("gb2312").length);
System.out.println("ISO-8859-1:"+abc.getBytes("ISO-8859-1").length);

输出如下:

3832154813577306424 length:19
UTF-8:19
unicode:40
gbk:19
gb2312:19
ISO-8859-1:19

当做数字:如当做长整型,则占用的内存大小为8字节。

这里有2倍以上的差距了吧。

那么我们如何在长整型和字节数组之间转换呢?

String abc = "3832154813577306424";System.out.println("3832154813577306424 length:"+abc.length());
System.out.println("long:"+ByteUtils.longToBytes(Long.parseLong(abc)).length);
byte[] bytes = ByteUtils.longToBytes(Long.parseLong(abc));
System.out.println("string:"+ByteUtils.bytesToLong(bytes));

输出如下:

3832154813577306424 length:19
long:8
string:3832154813577306424
public static byte[] longToBytes(long x) {ByteBuffer longBuffer = ByteBuffer.allocate(Long.BYTES);longBuffer.putLong(0, x);return longBuffer.array();
}
public static long bytesToLong(byte[] bytes) {return bytesToLong(bytes, 0, bytes.length);
}
public static long bytesToLong(byte[] bytes, int offset, int length) {ByteBuffer longBuffer = ByteBuffer.allocate(Long.BYTES);longBuffer.put(bytes, offset, length);longBuffer.flip();//need flipreturn longBuffer.getLong();
}

文章转载自 开源中国社区[https://www.oschina.net]

如何选择使用字符串还是数字呢?相关推荐

  1. JavaScript字符串转数字的5种方法及其陷阱

    2019独角兽企业重金招聘Python工程师标准>>> 摘要 :JavaScript 是一个神奇的语言,字符串转数字有 5 种方法,各有各的坑法! 原文: Converting St ...

  2. Java中怎么样检查一个字符串是不是数字呢

    问题:Java中怎么样检查一个字符串是不是数字呢 在解析之前,怎么样检查一个字符串是不是数字呢 回答一 这些通常是由一个简单的用户自定义函数去解决的(即,自带的 "isNumeric&quo ...

  3. 中传入字符串_JavaScript字符串转数字有什么方法

    JavaScript是一个神奇的语言,字符串转数字有5种方法,各有各的坑法!接下来通过本文给大家介绍JavaScript字符串转数字的5种方法及其陷阱,感兴趣的朋友一起看看吧 选择哪一种呢?什么时候选 ...

  4. 字符串与数字相互转化

    一.C中的方法 1.  c中字符串转换成数字:一些库函数 头文件:#include<stdlib.h> atof(),atoi(),atol(),atoll(),strtod(),strt ...

  5. js怎么把字符串转数字

    最近在掘金上看到一位大三的学生总结的一个js面试题:将字符串转换成数字.看了他的文章真让我想起去年的自己. parseInt(num); 还是写代码比较快乐:如下 arseInt(12) 12 par ...

  6. 如何将数据库中text字段中返回的数据转换成数组的形式,并且将字符串的数字转换成数字的形式显示

    如何将数据库中text字段中返回的数据转换成数组的形式,并且将字符串的数字转换成数字的形式显示 数据库text字段 数据库中的text字段在前端 界面返回的时候是成字符串的形式的,类似于下图 那么,在 ...

  7. 字符串乘以数字python_将字符串乘以数字!

    将字符串乘以数字! 34 前一阵子关于将字符串相乘存在一个挑战.它向我们展示了如何不仅可以将数字相乘,而且还可以将字符串相乘.但是,我们仍然无法正确地将数字乘以字符串.已经尝试过这样做,但这显然是错误 ...

  8. html将字符串转为数值,JavaScript字符串转数字的5种方法及其陷阱

    JavaScript 是一个神奇的语言,字符串转数字有 5 种方法,各有各的坑法!下面本篇文章就来介绍一下JavaScript字符串转数字的5种方法及其陷阱,希望对大家有所帮助. String 转换为 ...

  9. java取出字符串中的后四位_[原]Java面试题-将字符串中数字提取出来排序后输出...

    [Title][原]Java面试题-将字符串中数字提取出来排序后输出 [Date]2013-09-15 [Abstract]很简单的面试题,要求现场在纸上写出来. [Keywords]面试.Java. ...

最新文章

  1. 迷途指针,从百度百科上摘抄的,语言很幽默
  2. 【C语言探索之旅】 第一部分第六课:条件表达式
  3. 玩转Eclipse — 自动生成setter和getter方法
  4. php dede 发布时间_dede 采集到数据后,发布日期变为本地日期解决方法
  5. Android ListView使用
  6. 【转载】小米2进入recovery的方法
  7. mysql5.7无法启动问题
  8. 重定向拼接中文参数和特殊字符
  9. Function eregi() is deprecated
  10. DFS(深度优先遍历)走迷宫算法
  11. FileSystemObject ADO WScript.Shell
  12. Java邮件服务学习之一:邮件服务概述
  13. [BZOJ 3622]已经没有什么好害怕的了(Dp+容斥原理)
  14. html在浏览器中打开就是网站,浏览器打开网页的过程
  15. 超级详细的教程--如何写SCI
  16. 泉州信息工程学院 计算机考试,泉州信息工程学院教务网络管理系统成绩查询、网上选课查分登录入口...
  17. 一位医疗 AI 创业者的自述:这个行业到底需要什么样的产品?
  18. SuperMap iDesktop 提取影像边界裁剪去除无值区域处理方案
  19. 【C语言基础-」TurboC环境】-」bioskey函数详细分析
  20. 移动端最常用的四个框架

热门文章

  1. Linux高级权限管理
  2. 第一个Android项目HelloAndroid
  3. 大数据_Flink_Java版_状态管理(2)_算子状态---Flink工作笔记0061
  4. mycat集群执行带有join的sql语句时报错_can‘t find table define in schema_分片join---Linux运维工作笔记052
  5. AndroidStudio安卓原生开发_UI高级_自定义主题和样式---Android原生开发工作笔记129
  6. 去除eclipse打开后不断update的问题
  7. encoder.cpp(340) [feature_index.open(templfile, trainfile)]feature_index.cpp(174) [max_size == size]
  8. GetWindowRect和GetClientRect
  9. vc中把数据库记录表导入Excel
  10. 学习GNU Make (2): 规则