题目:
输入一个字符串和字节数,输出为按字节截取的字符串。但是要保证汉字不被截半,例如“人ABC”,4,应该截取为“人AB”,输入“人ABC们,6”,应该输出为“人ABC”而不是“人ABC+们的半个”。
问题分析:
-
如何判断一个字符是中文字符还是英文字符?
通过字符的字节数判断。一般来说,英文字符占1个字节,中文字符占2个字节。Java默认采用Unicode编码,即一个字符占2个字节,是比较浪费存储空间的。
-
要如何截取字符串?
可以通过遍历字符串的方式,将截取范围内的字符串存储到一个新的字符串中,然后打印输出。
关键点:如果要求截取子串的长度只差一个字符,但是接下来的字符是中文,要怎办?
当然是截取结果子串不保存这个中文字符。
-
截取的字符串采用什么存储比较好?
如果是多线程环境下,采用StringBuffer,如果是单线程环境下,采用StringBuilder。读书可以被修改的字符串,只是一个是线程安全,一个是线程不安全。StringBuilder执行效率高于StringBuffer。
原因:String类存储字符的方式是:英文字符占1字节,中文字符占2字节。可以减少所需存储空间,提高存储效率。我们才有StringBuilder存储截取的字符串,因为这里不涉及多线程,才用存储效率高的。
public class Test {
public static void main(String[] args) {
String str = "人ABC们";
Test3 test3 = new Test3();
String truncStr = test3.truncStr(str, 6);
System.out.println(truncStr);
}
// 判断是否是中文字符
public static boolean isChinese(char c) {
// valueOf(char c): 将char变量转为字符串
String s = String.valueOf(c);
// 获取字符串的字节数并判断长度
return s.getBytes().length > 1 ? true : false;
}
// 截取字符串的方法
public String truncStr(String str, int len) {
if (str == null || str.equals("") || len == 0) {
return "";
}
char[] charArray = str.toCharArray();
StringBuilder sb = new StringBuilder();
int count = 0; // 记录当前截取字符的长度
for (char cc : charArray) {
if (count < len) {
if (isChinese(cc)) {
// 表明是一个中文
// 如果要求截取子串的长度只差一个字符,但是接下来的字符是中文
if (count + 1 == len) {
return sb.toString(); //直接打印当前已存储的字符串
} else {
count += 2;
sb.append(cc); //直接存储中文字符
}
} else {
count += 1;
sb.append(cc); //直接存储英文字符
}
} else {
break;
}
}
return sb.toString();
}
}