分析:题目的要求是从字符串中按字节数截取,所以字符串转换为字节数组是肯定的,字母还好说,就占一个字节,问题的关键在于字符串中有汉字的出现,GBK编码中汉字字符是占两个字节的,两个字节分开无法识别,当截取的字节数最后一位是代表半个字符的字节时,运行结果中的字符串末尾会出现“?”以表示最后一个字节无法识别。所以需要在程序中将这种情况回避掉,只显示整个的汉字字符。
第一种方法:通过比较新子串和源字符串相同位置上的字符是否相等来判断新子串中最后一个字节是否可以识别,如果相同则说明最后截取的是一个完整的汉字,如果不同则说明新子串的字节数组最后一个字节是一个汉字的半边,需要舍弃,所以数组指针向左移一位,以保证完整的汉字输出。此方法条理清楚,可阅读性较强。
public static void byteSubStr(String str , int len)
{
String s = null; //初始化字符串s,赋值为空
if(str != null) //传入的字符串不能为空
{
byte[] a = null; //初始化字节数组,赋值为空
try
{
a = str.getBytes("GBK"); //将字符串转化为字节数组,GBK码表,此时字节数组的长度为14
}
catch (UnsupportedEncodingException e) //捕捉编码失败异常
{
e.printStackTrace();
}
//System.out.println("String length:"+a.length);打印字节数组的长度
if(a.length <= len)
{
s = str; //如果要求取出的字节长度大于字节数组应有长度,则将s初始化为str
}
else if(len > 0)
{
s = new String(a, 0, len); //如果字节长度在字节数组长度范围内,则根据要求取出长度len,创建新的字符串s。
int length = s.length(); //获取新字符串的长度
//System.out.println(s.length());
if(str.charAt(length - 1) != s.charAt(length-1))//如果原字符串中相应位置上的字符与
//新字符串相应位置上的字符不相等,说明新字符串中相应位置只有半个中文,则应该讲数组指针向左移一位,形成新的子串。
{
if(length < 2)
{
s = null; //如果新字符串的长度小于2,则将新字符串赋值为空。
}
else
{
s = s.substring(0, length - 1); //将符合条件的子串复制给s
}
}
}
}
System.out.println(s);
}
第二种方法:相比较而言,个人觉得第二种方法比较不容易看懂,需要费点儿功夫,首先,在字符串判断的使用使用的是三目运算符,看上去很赞,
接下来在判断新子串是否符合要求时使用了while方法,通过不断的循环比较,数组指针向左移动来获取到最后的字符子串。
public static voidbyteSubStr(String str, int length)
{
if (str == null)
System.out.println("String is null...");
else
{
int len = length; //获取要截取的字节数
//System.out.println("len:"+len);
//System.out.println("strlength:"+str.length());//8
String s = str.substring(0, str.length() < length ? str.length() : length);
//判断如果要截取的字节数长度大于原字符串本身的长度,则仍以原字符串为准,否则获取新子串。规则为包含头不包含尾。
//System.out.println("s1:"+s);
int byteLens = 0; //初始化字节数组长度
try
{
byteLens = s.getBytes("GBK").length; //按照GBK码表将原字符串或子串转为字节数组,并获取字节数组长度。
//System.out.println("byteLens:"+byteLens);
}
catch (UnsupportedEncodingException e) //捕获编码异常
{
e.printStackTrace();
}
while (byteLens > len) //如果字节数组长度大于要截取的字节数,说明有汉语字符的存在
{
int subLength = --length;
//System.out.println("subLength:"+subLength);
s = str.substring(0, subLength > str.length() ? str.length() : subLength);
//判断新子串长度和原子串长度,true返回原子串长度,false返回新子串长度
//System.out.println("s2:"+s);
try
{
byteLens = s.getBytes("GBK").length;
//System.out.println("byteLens:"+byteLens);
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
System.out.println("String:"+s);
}
}
|