1.基本思路
每个大小写字母都有对应唯一的ASCII码值,在计算机内部储存一个字符就实质上是储存其ASCII码值。而每个大小写字母对应的ASCII码值相差32(二进制相差0b100000,十六进制相差0x20)。所有ASCII码均可用7位二进制数表示,当某个字母的大小写分别用其对应ASCII码值的二进制形式表示时,只有第6位数字不同。大写字母的第6位为0,小写字母的第6位为1.(如,'u’的二进制ASCII码值是0b1110101,'U’的二进制ASCII码值是0b1010101)。此时可用位运算符来改变二进制ASCII码的第6位数字,来达到大小写转换的效果。
2.实现代码
(1)所有字母转为小写字母
static void toLowerCase(char[] array) {
for (int i = 0; i < array.length; i++) {
/*
* 按位或的特点: 0和任何数(即0或1)位或运算,其结果还是原来那个数(0或1)(即除第6位数以外,其他位的二进制数不变)
* 1和0(大写字母的第6位为0)位或运算,其结果为1(运算后第6位变为1,即变成了小写字母);
* 1和1(小写字母的第6位为1)位或运算,其结果为1(运算后第6位还是1,即小写字母位或运算后还是小写字母);
*/
array[i] = (char) (array[i] | 0b0100000);
}
}
(2)所有字母转为大写字母
static void toUpperCase(char[] array) {
for (int i = 0; i < array.length; i++) {
/*
* 按位与的特点: 1和任何数(0或1)位与运算,其结果还是原来那个数(0或1)(即除第6位数以外,其他位的二进制数不变)
* 0和1(小写字母的第6位为1)位与运算,其结果为0(运算后第6位变为0,即变成了大写字母);
* 0和0(大写字母的第6位为0)位或运算,其结果为0(运算后第6位还是0,即大写字母位或运算后还是大写字母);
*/
array[i] = (char) (array[i] & 0b1011111);
}
}
(3)所有字母大小写互转
/**
* 大小写字母相互转换
* @param array
* @return
*/
static char[] exchangeUpperAndLower(char[] array) {
for (int i = 0; i < array.length; i++) {
/*
* 按位异或的特点: 0和任何数(0或1)位与运算,其结果还是原来那个数(0或1)(即除第6位数以外,其他位的二进制数不变)
* 1和1(小写字母的第6位为1)位异或运算,其结果为0(运算后第6位变为0,即变成了大写字母);
* 1和0(大写字母的第6位为0)位或运算,其结果为1(运算后第6位变为1,即变成了小写字母);
*/
array[i] = (char) (array[i] ^ 0b0100000);
}
return array;
}
3.测试结果
1)大写转小写或小写转大写
char[] letters = { 'a', 'B', 'e', 'G', 'z', 'f', 'u', 'X' }; // 定义一个原数组
char[] copiedLetters1 = Arrays.copyOf(letters, letters.length); // 定义原数组的一个副本数组
char[] copiedLetters2 = Arrays.copyOf(letters, letters.length); // 定义原数组的另一个副本数组
toLowerCase(copiedLetters1); // 调用字符转小写的方法
toUpperCase(copiedLetters2); // 调用字符转大写的方法
System.out.println("原字符数组的各元素分别是:" + Arrays.toString(letters));
System.out.println("字符数组的所有元素转换为小写分别是:" + Arrays.toString(copiedLetters1));
System.out.println("字符数组的所有元素转换为大写分别是:" + Arrays.toString(copiedLetters2));
控制台输出:
2)大小写相互转换
public static void main(String[] args) {
String str = "aDcbEKjL";
char[] chs = exchangeUpperAndLower(str.toCharArray());
System.out.println(Arrays.toString(chs));
}