背景
将数据库字段映射到Java实体类时遇到的问题,如user_id
需要映射成userId
。
talk is cheap , show me the code
一共两种实现方式:
- 操作字节数组,性能较高,可读性较差
- 使用String类提供的方法实现,性能较低
高性能实现方式
/**
* 将下划线命名转换成驼峰式命名
* 例:user_id -> userId
* ASCII表
* Dec Char Dec Char Dec Char Dec Char
* --------- --------- --------- ----------
* 0 NUL (null) 32 SPACE 64 @ 96 `
* 1 SOH (start of heading) 33 ! 65 A 97 a
* 2 STX (start of text) 34 " 66 B 98 b
* 3 ETX (end of text) 35 # 67 C 99 c
* 4 EOT (end of transmission) 36 $ 68 D 100 d
* 5 ENQ (enquiry) 37 % 69 E 101 e
* 6 ACK (acknowledge) 38 & 70 F 102 f
* 7 BEL (bell) 39 ' 71 G 103 g
* 8 BS (backspace) 40 ( 72 H 104 h
* 9 TAB (horizontal tab) 41 ) 73 I 105 i
* 10 LF (NL line feed, new line) 42 * 74 J 106 j
* 11 VT (vertical tab) 43 + 75 K 107 k
* 12 FF (NP form feed, new page) 44 , 76 L 108 l
* 13 CR (carriage return) 45 - 77 M 109 m
* 14 SO (shift out) 46 . 78 N 110 n
* 15 SI (shift in) 47 / 79 O 111 o
* 16 DLE (data link escape) 48 0 80 P 112 p
* 17 DC1 (device control 1) 49 1 81 Q 113 q
* 18 DC2 (device control 2) 50 2 82 R 114 r
* 19 DC3 (device control 3) 51 3 83 S 115 s
* 20 DC4 (device control 4) 52 4 84 T 116 t
* 21 NAK (negative acknowledge) 53 5 85 U 117 u
* 22 SYN (synchronous idle) 54 6 86 V 118 v
* 23 ETB (end of trans. block) 55 7 87 W 119 w
* 24 CAN (cancel) 56 8 88 X 120 x
* 25 EM (end of medium) 57 9 89 Y 121 y
* 26 SUB (substitute) 58 : 90 Z 122 z
* 27 ESC (escape) 59 ; 91 [ 123 {
* 28 FS (file separator) 60 < 92 \ 124 |
* 29 GS (group separator) 61 = 93 ] 125 }
* 30 RS (record separator) 62 > 94 ^ 126 ~
* 31 US (unit separator) 63 ? 95 _ 127 DEL
*/
public class ToCamelUtil {
/**
* 下划线对应的ASCII
*/
private static final byte ASCII_UNDER_LINE = 95;
/**
* 小写字母a的ASCII
*/
private static final byte ASCII_a = 97;
/**
* 大写字母A的ASCII
*/
private static final byte ASCII_A = 65;
/**
* 小写字母z的ASCII
*/
private static final byte ASCII_z = 122;
/**
* 字母a和A的ASCII差距(a-A的值)
*/
private static final byte ASCII_a_A = ASCII_a - ASCII_A;
/**
* 将参数b转换为大写字母,小写字母ASCII范围(97~122)
* 0. 判断参数是否为小写字母
* 1. 将小写字母转换为大写字母(减去32)
*/
private static byte toUpper(byte b) {
if (b >= ASCII_a && b <= ASCII_z) {
return (byte) (b - ASCII_a_A);
}
return b;
}
/**
* 交换下划线和其后面字符的下标
* 将column从下划线命名方式转换成驼峰命名方式
* 0. 找到`_`符号的ASCII码(95)对应的下标
* 1. 将下划线的下标的下一个元素转换为大写字段(如果是小写字母的话)并放到下划线对应的下标
* 2. 将下划线下标的下一个元素设置为下划线
* 3. 返回数组
*
* @param column 字段名称
*/
private static byte[] changeIdx(String column) {
byte[] bytes = column.getBytes();
for (int i = 0; i < bytes.length; i++) {
if (bytes[i] == ASCII_UNDER_LINE) {
if (i < bytes.length - 1) {
bytes[i] = toUpper(bytes[i + 1]);
bytes[i + 1] = ASCII_UNDER_LINE;
i++;
}
}
}
return bytes;
}
/**
* 去除所有下划线
* 0. 新创建一个数组
* 1. 将所有非下划线字符都放入新数组中
*
* @param bytes 原始数组
* @return 处理后的字节数组
*/
private static byte[] removeUnderLine(byte[] bytes) {
// 存放非下划线字符的数量
int count = 0;
for (byte b : bytes) {
if (b == ASCII_UNDER_LINE) {
continue;
}
count++;
}
byte[] nBytes = new byte[count];
count = 0;
for (byte b : bytes) {
if (b == ASCII_UNDER_LINE) {
continue;
}
nBytes[count] = b;
count++;
}
return nBytes;
}
/**
* 将下划线命名转换驼峰式命名
* 0. 转换成大写,交换下标
* 1. 去除所有下划线
*
* @param column 原始字段
* @return 新字段
*/
public static String change(String column) {
byte[] bytes = changeIdx(column);
bytes = removeUnderLine(bytes);
return new String(bytes);
}
public static void main(String[] args) {
System.out.println(change("user_id"));//打印结果: userId
System.out.println(change("hello_world_to_lucky_man"));//打印结果: helloWorldToLuckyMan
}
}
低性能实现方式
/**
* 将下划线命名转换成驼峰式命名通过String类
* 例:user_id -> userId
*/
public class ToCamelUtilByString {
/**
* 将下划线命名转换驼峰式命名
* 0. 先将字符串以下划线字符进行分割
* 1. 从第1个下标开始将字符串的首字母转换成大写
* 2. 拼接所有字符串
* 3. 返回新的字符串
*
* @param column 字段名称
* @return 新的字段名称
*/
public static String changeByStr(String column) {
String[] s = column.split("_");
if (s.length == 0) {
return column;
}
String res = s[0];
for (int i = 1; i < s.length; i++) {
res += s[i].substring(0, 1).toUpperCase() + s[i].substring(1);
}
return res;
}
public static void main(String[] args) {
System.out.println(changeByStr("user_id"));//打印结果: userId
System.out.println(changeByStr("hello_world_to_lucky_man"));//打印结果: helloWorldToLuckyMan
}
}
两种实现方式性能对比
/**
* 性能测试
*/
public class TestPerformance {
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
// 高性能实现方式
ToCamelUtil.change("hello_world_i_love_u");
}
System.out.println(System.currentTimeMillis() - start);// 打印结果:18(毫秒)
start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
// 低性能实现方式
ToCamelUtilByString.changeByStr("hello_world_i_love_u");
}
System.out.println(System.currentTimeMillis() - start);// 打印结果:50(毫秒)
}
}
来源:CSDN
作者:luckyman98
链接:https://blog.csdn.net/luckyman98/article/details/104054005