题目:

输入一个字符串和字节数,输出为按字节截取的字符串。但是要保证汉字不被截半,例如“人ABC”,4,应该截取为“人AB”,输入“人ABC们,6”,应该输出为“人ABC”而不是“人ABC+们的半个”。

问题分析:

  1. 如何判断一个字符是中文字符还是英文字符?

    通过字符的字节数判断。一般来说,英文字符占1个字节,中文字符占2个字节。Java默认采用Unicode编码,即一个字符占2个字节,是比较浪费存储空间的。

  2. 要如何截取字符串?

    可以通过遍历字符串的方式,将截取范围内的字符串存储到一个新的字符串中,然后打印输出。

    关键点:如果要求截取子串的长度只差一个字符,但是接下来的字符是中文,要怎办?

    当然是截取结果子串不保存这个中文字符。

  3. 截取的字符串采用什么存储比较好?

    如果是多线程环境下,采用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();
	}
}