首页 > 代码库 > 一个截取字符串函数引发的思考
一个截取字符串函数引发的思考
背景
前些天,遇到这样一个问题,问题的内容如下:
要求编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。但是要保证汉字不被截半个,如“我ABC”, 4,截取后的效果应该为“我AB”,输入“我ABC汉DEF”, 6,应该输出为“我ABC”,而不是“我ABC+汉的半个”。
问题
刚看到这个问题的时候,以为还是很简单的,但写出来之后,发现并不是想要的效果。回想一下当时的思路,就发现刚开始思考的时候,就没有考虑好,而且把汉字会导致的问题给忽略了,就这样没有一个完整的思路,就直接开始写代码了。大家可想而知,写出来的效果当然不会是你想要的了。
既然题目中已经要求了汉字存在时应该出现什么样的结果,那么我们就应该考虑,如何把英文和中文都统一成一种编码,而不是对它们进行单独的处理。设想一下,如果程序中对它们进行单独的处理,那么会出现什么样的问题呢?这个稍后再说。
实现
遇到这些问题之后,总得想办法解决吧,于是在网上找到了一种解决方案,主旨是,统一中英文的编码方式,即在GBK的编码方式下,把要截取的字符串转换为字节数组,此时,一个汉字就会转换为两个负数,例如,“我”就会转换为“-50, -46”。然后再针对截取到的负数的个数进行处理,就可以把汉字的问题解决了。
截取函数代码
<span style="font-family:Microsoft YaHei;font-size:12px;">/** * 截取要点: * 1. 首先将字符串转换成字节数组,再将字节数组的每个元素拿出来,判断有无负数(一个汉字为两个负数),即可知道有没有汉字 * 2. len:是将字符串转换成字节数组后,要截取的长度,如“我ABC你”的字节数组长度为7(-50,-46,65,66,67,-60,-29) * ,而截取的是6(-50,-46,65,66,67,-60) * 3. 对截取的字节数组(-50,-46,65,66,67,-60),统计负数的个数 * 4. String里的 substring 方法将双字节的汉字当成一个字节的字符(UCS2字符) * * @param str * @param len * @return */ public static String subString(String str, int len) { // 判断字符串是否为空 if (str == null && "".equals(str)) { return null; } // 将字符串中的char数组转换成指定编码方式的byte数组的函数 byte[] strBytes = null; try { strBytes = str.getBytes("GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } // 得到字符串的长度 int strLen = strBytes.length; // 判断截取字符串的长度是否在判断的范围内,否则返回原串 if (len >= strLen || len < 1) { return str; } // 打印出字符串长度和截取的长度 System.out.println("strBytes.length = " + strBytes.length); System.out.println("len = " + len); int count = 0; for (int i = 0; i < len; i++) { // 将每个字节数组转换为整型数,以为后面根据值的正负来判断是否为汉字 int value = http://www.mamicode.com/strBytes[i];>测试代码
<span style="font-family:Microsoft YaHei;font-size:12px;">/** * @param args */ public static void main(String[] args) { // 情况一 System.out.println("------------ 情况一 ------------"); String inStr = "我ABC你"; String str = subString(inStr, 6); System.out.println(str); // 我ABC // 情况二 System.out.println("------------ 情况二 ------------"); inStr = "我ABC汉DEF"; str = subString(inStr, 1); System.out.println(str); // 我 // 情况三 System.out.println("------------ 情况三 ------------"); inStr = "我AB爱孩子CDEF"; str = subString(inStr, 9); System.out.println(str); // 我AB爱孩 // 情况四 System.out.println("------------ 情况四 ------------"); inStr = "ABCDEF"; str = subString(inStr, 4); System.out.println(str); // ABCD }</span>
测试结果
思考
通过这个题目,给了我很多的启示,首先,在“下笔”之时,就应该考虑到灵活性的问题,虽然这里只是中英文的字符串截取,但是如果再增加一种其他语言呢?扩展性就没有那么好了,这也是上边所提到的问题。好的设计是一方面,代码的实现上,也要做到解耦合。同时,这也提醒了我,在考虑问题的时候,首先不能一头扎到细节中,而是先要有一个全局观,对整体有个全面的了解,将具体的问题抽象化、简单化,层层剖析;做完这一点之后,才是对具体的问题具体分析。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。