`
zhangchunxiao
  • 浏览: 16754 次
社区版块
存档分类
最新评论

正确选择使用字符串或者数字

 
阅读更多

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

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

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

 ByteUtils代码如下:

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();  
}  

 (本文摘自http://yangshangchuan.iteye.com/blog/2239571

分享到:
评论

相关推荐

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

    例如,在数据校验、格式化输出或者解析特定格式的数据时,可能需要找出字符串中数字的位置。本篇文章将详细介绍如何在C#中实现这一功能。 #### 解决方案概述 为了实现上述需求,我们需要完成以下步骤: 1. **读取...

    生成随机字符串(字符串,数字)

    若要保证字符分布更均匀,可以使用更复杂的随机数生成算法,或者对生成的字符串进行一定的调整。 总的来说,生成随机字符串和数字在C#编程中是一项基础且实用的技能。通过掌握`Random`类的使用和字符串操作,你可以...

    java字符串类型数字设置千分位分隔

    创建一个`DecimalFormat`实例后,我们可以使用`format()`方法将数字转换为字符串。 下面是一个简单的示例,展示了如何使用`DecimalFormat`设置千分位分隔: ```java import java.text.DecimalFormat; public ...

    统计字符串中数字的个数

    ### 统计字符串中数字的个数 #### 实验内容 本实验的主要目的是设计并实现一个程序,用于统计一个特定字符串中所有数字的出现次数,并按照数字从小到大的顺序输出这些数字及其出现次数。 #### 输入格式 - **Input...

    delphi实现数字和字母组合的字符串数字部分不断自加

    以上就是使用Delphi实现数字和字母组合的字符串数字部分不断自加的具体方法。在实际应用中,你可能需要根据具体需求调整代码,例如处理不同长度的数字部分,或者支持其他类型的自增逻辑。这个过程涉及到字符串操作、...

    C/C++ 字符串转化成数字,支持任意进制

    - 对于效率,可能需要考虑优化算法,比如预计算进制幂表,避免重复计算,或者使用更高效的字符串处理方法。 7. **内存管理与安全性**: - 确保在处理字符串时避免内存泄漏,使用智能指针或其他内存管理策略。 - ...

    判断字符串是否只有数字

    在本例中,我们使用了正则表达式 `[0-9]*` 来判断一个字符串是否只由数字组成。这里的关键点包括: - **`[0-9]`**:表示从0到9的任意单个数字。 - **`*`**:表示前面的模式可以出现零次或多次。 因此,`[0-9]*` ...

    C语言检测字符串是否为json字符串

    但是,开发者通常会使用类似的方法来编写这样的函数,确保输入的字符串符合JSON的语法规则,从而在C语言项目中正确地处理JSON数据。对于大型项目,可能会选择成熟的C JSON库,如cJSON或Jansson,它们提供了完整的...

    数值运算字符串转换成数字.zip

    1. **内置函数**:在某些SQL方言中,如MySQL,你可以使用`STR_TO_DATE()`函数或`CAST()`/`CONVERT()`函数来尝试将字符串转换为数字。但这些函数并不能直接处理算术表达式,只能用于简单的数字字符串转换。 2. **...

    给定一个只包含数字[0…9]的字符串,请使用字符中的某些字符,构建一个能够整除15的最大整数,注意字符中的每个字符只能使用一次

    该问题要求使用给定的数字字符串,构建一个能够整除15的最大整数,注意每个字符只能使用一次。下面是对该问题的详细解析和解决方案。 问题描述: 给定一个只包含数字[0…9]的字符串,请使用字符中的某些字符,构建...

    西门子PLC字符串转实数

    在使用“VAL”函数时,需要确保字符串格式正确,否则可能引发错误。 ```scl VAR strValue : STRING; // 输入字符串 realValue : REAL; // 转换后的实数 END_VAR realValue := VAL(strValue); // 调用VAL函数进行...

    .NET标准格式数字字符串

    在这种情况下,你可以使用`ToString()`方法配合标准格式说明来确保字符串格式正确。 例如,如果你需要将一个`double`类型的数值写入到数据库的`DECIMAL(10,2)`字段,可以使用`"F2"`格式: ```csharp double ...

    matlab开发-读取数字字符串

    其中,`input`是要读取的数据源,可以是字符串或者字符数组;`formatSpec`定义了数据的格式,比如数值类型、精度等;`output`是读取到的数据,会根据`formatSpec`的定义返回相应类型的变量;`maxNumChars`可选,用于...

    SQL Server中,在“整型数字”和“字符串表示的十六进制数字”之间进行转换的函数

    通常,如果你需要将整型数字转换为十六进制字符串,可以使用内置的 `CONVERT` 函数配合 `style` 参数。例如,如果你有一个整数变量 `@myInt`,你可以使用以下语句将其转换为十六进制: ```sql SELECT CONVERT...

    delphi 实现截取字符串中中文+英文混合截取

    总结来说,处理Delphi中的中文和英文混合字符串截取,关键在于理解Unicode字符串的特性,正确选择和使用字符串截取函数,并在必要时进行字节对齐和编码转换。通过这样的方式,我们可以确保在处理多语言文本时不会...

    QT 收到下位机16进制数转换字符串显示

    4. **显示在QLineEdit**:最后,使用QLineEdit的`setText()`方法将转换后的16进制字符串设置为其显示内容。例如,`lineEdit->setText(hexString)`。 为了确保显示的可靠性,你可能还需要考虑以下几点: - **错误...

    Android字符串运算的计算器

    我们可以使用正则表达式来分割字符串,提取数字和操作符。 2. **表达式树(Expression Tree)**:为了正确处理运算符的优先级,我们通常会构建一个表达式树。每个节点代表一个操作或者一个数字,而边表示操作的执行...

    字符串查找的汇编程序

    5. **输出格式化**:使用 `ADD DL, 30H` 将数字转换成ASCII码以便正确输出。 #### 五、总结 本程序通过简单的汇编语言指令实现了两个字符串的匹配查找,并且能够统计出匹配的数量。虽然程序较为基础,但它展示了...

    C#字符串计算公式处理

    1. **分词**:使用`Split`方法按运算符(如"+","-"等)拆分字符串,得到包含数字和变量的字符串数组。 2. **变量解析**:识别出代表数值的变量(如“基本工资”和“奖金”),这可能需要查找预先定义的字典或者从...

    ABB机器人在RobotStudio中进行数字与字符串相互转换的具体方法.docx

    ABB机器人在RobotStudio中进行数字与字符串相互转换是编程中常见的操作,特别是在处理用户输入或者进行数据处理时。本文将详细讲解如何在RobotStudio中利用Rapid语言进行这些转换。 首先,我们需要打开ABB的...

Global site tag (gtag.js) - Google Analytics