`

如何选择使用字符串还是数字呢?

    博客分类:
  • java
阅读更多

 

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

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

然而,对于大数据处理来说,这个可不是小事,从字符串替换为数字类型,可以极大地节省内存、磁盘存储以及网络带宽,减少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 flip
    return longBuffer.getLong();
}

 

 

 

 

 

 

 

5
2
分享到:
评论
6 楼 yangshangchuan 2015-10-01  
liujun422134235 写道
楼主,请问 ByteBuffer longBuffer = ByteBuffer.allocate(Long.BYTES);  这句中的Long.BYTES这个你是从哪来的?是原生java.lang.Long中的吗?那个这长度你固定了吗?如果在再长这个长度该如何确定?

liujun422134235 写道
楼主,请问 ByteBuffer longBuffer = ByteBuffer.allocate(Long.BYTES);  这句中的Long.BYTES这个你是从哪来的?是原生java.lang.Long中的吗?那个这长度你固定了吗?如果在再长这个长度该如何确定?



java.lang.Long中:

public static final int BYTES = SIZE / Byte.SIZE;
public static final int SIZE = 64;

java.lang.Byte中:

public static final int SIZE = 8;
5 楼 liujun422134235 2015-09-30  
楼主,请问 ByteBuffer longBuffer = ByteBuffer.allocate(Long.BYTES);  这句中的Long.BYTES这个你是从哪来的?是原生java.lang.Long中的吗?那个这长度你固定了吗?如果在再长这个长度该如何确定?
4 楼 white_crucifix 2015-09-01  
其实我相信绝大多数的系统还达不到因这个原因而引起性能瓶颈的地步,但是什么样的数据用什么样的类型当然是极好的,只是实践当中,确实从项目到人,很多地方都崇尚全部用字符串,甚至是时间类型的字段也用string。
3 楼 yixiandave 2015-09-01  
hanjiangit 写道
qqt31 写道
用String表达数字的原因是高精度计算时用BigDecimal

不是有double嘛

高精度计算不能用double,虽然double精度比float高但是依然会出错。之前碰到过用double计算结果后面多出来个莫名其妙的尾巴
2 楼 hanjiangit 2015-09-01  
qqt31 写道
用String表达数字的原因是高精度计算时用BigDecimal

不是有double嘛
1 楼 qqt31 2015-09-01  
用String表达数字的原因是高精度计算时用BigDecimal
0 楼 eggliwen 2015-08-31  
  

相关推荐

    java基础-给出一个随机字符串,判断有多少字母?多少数字?

    在实际开发中,我们需要根据实际情况选择合适的方法来判断字符串中的字母和数字。本文仅供初学者参考,旨在提供一种基本的解决方案。 本篇文章为大家详细介绍了如何使用Java语言来判断随机字符串中的字母和数字,...

    oracle 如何判断一个字符串能否转换为数字?

    可以使用`TRANSLATE`函数将所有可能的数字字符(包括小数点、正负号和科学计数法中的“E”或“e”)替换为固定的字符,然后比较替换后字符串的大小,以此来判断原字符串是否可以转换为数字。 **步骤**: 1. **定义...

    oracle通过sql实现字符串转数字oracle函数

    最后,当我们谈论“字符串的最终排序”时,使用转换后的数字字段进行排序将更准确,因为字符串按照字典顺序排序,而数字则按照数值大小排序。例如: ```sql SELECT * FROM your_table ORDER BY TO_NUMBER(str_...

    获取一个字符串中的数字组

    标题中的“获取一个字符串中的数字组”是指从包含数字和非数字字符的字符串中提取连续的数字,并将它们作为整数处理。描述中提到的任务是输入一个字符串,例如"a123x456_17960? 302tab5876",从中找出所有的连续数字...

    详解C++中十六进制字符串转数字(数值)

    详解C++中十六进制字符串转数字(数值) 主要有两个方法,其实都是对现有函数的使用:  方法1: sscanf()  函数名: sscanf 功 能: 从字符串格式化输入 用 法: int sscanf(char *string, char *format[,...

    字符串转数字

    "字符串转数字" 字符串转数字是指将字符串类型的数据转换为数字类型的数据,例如将字符串 "123" 转换为整数 123。这种转换在编程中非常常见,例如在用户输入验证、数据处理、算法实现等方面都需要进行字符串到数字...

    将数字从字符串中提取

    本示例的主题是“将数字从字符串中提取”,这是一个常见的需求,特别是在数据分析、文本处理或日志分析等场景。以下我们将深入探讨如何实现这个功能,并结合源码进行讨论。 首先,我们要了解字符串的基本操作。在...

    判断字符串是否为数字

    以上介绍了四种判断字符串是否为数字的方法,包括逐字符检查、使用正则表达式、利用 `String.matches()` 方法以及基于 ASCII 值的比较。每种方法都有其适用场景和特点,开发者可以根据具体需求选择最合适的方式。...

    获取字符串中的数字(两种方法)

    根据给定的信息,本文将详细介绍如何通过两种方法在C#编程语言中提取字符串中的数字。 ### 一、问题背景 在处理文本数据时,我们经常需要从字符串中提取出特定的信息,比如数字。例如,在一个包含混合字母和数字的...

    C#输入字母+数字的字符串 统计数字出现的位置

    根据给定的信息,本文将详细解释如何在C#中实现对包含字母与数字混合的字符串进行处理,以找出所有数字字符出现的位置。 ### C# 输入字母+数字的字符串,统计数字出现的位置 #### 问题背景 在实际开发过程中,经常...

    判断一个字符串或字符串中的一个字符是否为数字类型

    在编程领域,判断一个字符串或字符串中的一个字符是否为数字类型是常见的...综上所述,判断字符串或字符是否为数字类型,可以依据具体编程语言选择合适的方法,同时要注意处理潜在的安全风险,确保程序的稳定性和效率。

    从字符串中提取连续的字符数字转换为整数

    我们使用了一个标志变量find来判断字符串中是否有数字字符,如果有则退出循环,否则重新输入字符串。 知识点7:输入输出 在本文档中,我们使用了printf函数来输出结果,并使用gets函数来读取用户输入的字符串。...

    cad 字符串里自动提取数字求和

    "cad 字符串里自动提取数字求和"这个主题是针对这样的需求,它涉及到如何从复杂的字符串中识别并提取数字,然后对这些数字进行求和操作,而忽略文字和特殊字符。 在CAD环境中,LISP(List Processor,列表处理器)...

    字符串和数字转换 C++ vs2008

    在C++编程环境中,Visual Studio 2008(VS2008)是一个常用的开发工具,它提供了丰富的库和功能来支持字符串和数字之间的转换。在这个主题中,我们将深入探讨如何在C++中实现字符串到数字以及数字到字符串的转换。 ...

    C/C++字符串,字符转数字,数字转字符

    示例代码中演示了如何使用itoa()函数和gcvt()函数进行数字到字符串的转换。在面试例题1中,使用itoa()和gcvt()函数实现了整数和浮点数到字符串的转换,并通过参数指定了转换的细节。面试例题2演示了不使用库函数,...

    postgresql数字结尾字符串分割排序说明

    ### PostgreSQL数字结尾字符串分割排序详解 #### 功能概述 本文档旨在详细介绍如何通过自定义函数在PostgreSQL数据库中实现一种特殊的排序方式:对于以数字结尾的字符串,首先将其分为两部分,一部分为非数字字符串...

    VBA示例之 从字符串提取纯数字

    本示例主要探讨如何利用VBA从字符串中提取纯数字,这对于处理含有混合文本和数字的数据时非常有用。下面我们将深入讲解这个主题。 首先,我们需要了解VBA中的字符串函数,它们是实现这一目标的关键。主要有`Mid`、`...

    C语言字符串数字提出.zip

    标题 "C语言字符串数字提出.zip" 涉及的核心知识点是C语言中处理字符串和提取数字的方法。在C语言中,字符串是由字符组成的数组,而从字符串中提取数字则需要运用到字符串处理函数和数值转换函数。下面我们将深入...

    将字符串里面的数字进行截取方法

    根据给定的文件信息,本文将详细介绍如何在C#中实现从字符串中截取数字的方法。这种方法通过遍历字符串中的每个字符,判断其是否为数字或数字符号(如正负号),并将其添加到结果中。该方法适用于任何包含数字与非...

    汇编统计字符串数字及字符个数

    这个任务要求我们编写一段程序,能够区分字符串中的字母和数字,并将它们的个数分别存储到预定义的变量中。以下是对这个任务的详细解析: 1. **字符串定义**: 在汇编语言中,字符串通常以ASCII码表示。可以使用`...

Global site tag (gtag.js) - Google Analytics