java基础知识回顾之---java String final类普通方法的应用之“按照字节截取字符串”
/*
需求:在java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是四个字符。
但对应的字节数不同,一个汉字占两个字节。
定义一个方法,按照最大的字节数来取子串。
如:对于“ab你好”,如果取三个字节,那么子串就是ab与“你”字的半个,
那么半个就要舍弃。如果去四个字节就是“ab你”,取五个字节还是“ab你”.
*/
代码:其实是一个解码和编码的问题,要明白UTF-8码表和GBK码表的区别,UTF-8中用三个字节代表一个汉字,GBK使用2个字节代表一个汉字。
且在码表中都是用数字存放这些汉字。例如在GBK码表中,“你”为“-60 -29”;“好”为“-70 -61”,"谢"为"-48 -69".
我们把字符串先变成字节,按字节截取字符串。也就是先编码成某个码表中的数字,然后在把数字翻译过来,也就是查码表。对于GBK码表来说,两个数字代表一个汉字,且一般汉字用负数代表。那么我们可以来统计负数的个数count来决定是否舍弃半个汉字的问题,然后在判断负数的个数的奇偶性,如果count是奇数,则截取最后一个数字,舍弃半个汉字,解码输出,如果是偶数,全部解码输出。
public class Test {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String str = "ab你好cd谢谢";// 97 98 -60 -29 -70 -61 99 100 -48 -69 -48 -69
int len = str.getBytes("gbk").length;
for(int x=0; x<len; x++){
System.out.println("截取"+(x+1)+"个字节结果是:"+cutStringByByte(str, x+1));
}
// int len = str.getBytes("utf-8").length;
// for(int x=0; x<len; x++){
// System.out.println("截取"+(x+1)+"个字节结果是:"+cutStringByU8Byte(str, x+1));
// }
}
/* String str1 = "琲";//-84 105
byte[] buf = str1.getBytes("gbk");
for(byte b : buf){
System.out.print(" "+b);//-84 105
*/
/**
* 使用Utf-8按照字节截取字符串,Utf-8用3个字节代表一个汉字。
*/
public static String cutStringByU8Byte(String str, int len) throws IOException {
byte[] buf = str.getBytes("utf-8");//编码
System.out.println(buf);
int count = 0;
for(int x=len-1; x>=0; x--){
if(buf[x]<0)
count++;
else
break;
}
if(count%3==0)
return new String(buf,0,len,"utf-8");//解码
else if(count%3==1)
return new String(buf,0,len-1,"utf-8");
else
return new String(buf,0,len-2,"utf-8");
}
/**
* 使用字节截取字符串,gbk默认一个汉字为2个字节,编码表用两个数字代表一个汉字。
* (60 -29 -70 -61)代表你好
* 思路:我们可以记录负数的个数,
* 如果数字的个数为偶数,不用截取,没有半个汉字的情况,
* 如果负数的个数为奇数,那么加入有5个数字,那么最后一个数字舍弃。变为4个数字,再解码。
* @param str
* @param len
* @return
* @throws IOException
*/
public static String cutStringByByte(String str,int len) throws IOException{
byte[] buf = str.getBytes("gbk");//把指定编码的字符串转化为字节,存放到字节数组中,编码
int count = 0;
for(int x=len-1; x>=0; x--){//从数组的最后面开始循环,记录负数的个数
if(buf[x]<0)//汉字的编码表为负数
count++;
else
break;
}
if(count%2==0)//负数的个数为偶数,不截取
return new String(buf,0,len,"gbk");//解码
else
return new String(buf,0,len-1,"gbk");//舍弃一位数字,解码
}
}
java基础知识回顾之---java String final类普通方法的应用之“按照字节截取字符串”的更多相关文章
- java基础知识回顾之---java String final类普通方法
辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /* * 按照面向对象的思想对字符串进行功能分类. * ...
- java基础知识回顾之---java String final类普通方法的应用之“两个字符串中最大相同的子串”
/* * 3,两个字符串中最大相同的子串. * "qwerabcdtyuiop" * "xcabcdvbn" * * 思路: * 1,既然取得是最大子串,先看 ...
- java基础知识回顾之---java String final类之intern方法
public class StringObjectDemo { /** * @param args */ public static void main(String[] args) { String ...
- java基础知识回顾之java Thread类学习(八)--java.util.concurrent.locks(JDK1.5)与synchronized异同讲解
看API文档介绍几个方法: JDK1.5中提供了多线程的升级解决方案: 特点: 1.将同步synchronized显示的替换成Lock 2.接口Conditio ...
- java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)
上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // ...
- java基础知识回顾之java集合类-Properties集合
/** java.lang.Object |--java.util.Dictionary<K,V> |--java.util.Hashtable<Object,Obje ...
- java基础知识回顾之---java String final类 容易混淆的java String常量池内存分析
/** * 栈(Stack) :存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放 在常量池中). 堆(heap):存 ...
- java基础知识回顾之---java String final类普通方法的应用之“模拟字符串Trim方法”
/* * 4,模拟一个trim功能一致的方法.去除字符串两端的空白 * 思路: * 1,定义两个变量. * 一个变量作为从头开始判断字符串空格的角标.不断++. * 一个变量作为从尾开始判断字符串空 ...
- java基础知识回顾之---java String final类普通方法的应用之“子串在整串中出现的次数”
/* * 2 一个子串在整串中出现的次数. * "loveerlovetyloveuiloveoplove" * 思路: * 1,要找的子串是否存在,如果存在获取其出现的位置.这个 ...
随机推荐
- 向CodeBlocks的Project中添加calss文件时,出现No such file or directory错误的解决方案
我们在CodeBlocks中编写程序时,一般要建立工程.现在建立工程first,然后建立类文件Person,并将其添加到first中, int main() { Person p; p.display ...
- 更新win7资源管理器
更新exeplorer.exe: 1.方法1: void RefreshExplorer() { ]; SHELLEXECUTEINFOA shellExeInfo={}; shellExeInfo. ...
- Linux下安装Websphere MB所需的系统rpm包
很少使用到Linux,这次刚好用户有一个在linux下搭建Websphere MB/MQ的任务.试了几次都不行,经过多方打听,询问原来是少了rpm包的问题,但是,具体包名不详.. --#mount / ...
- php 获取数组第一个值的方法分享
以下是对使用php实现获取数组第一个值的方法进行了详细的分析介绍,需要的朋友可以过来参考下 reset (PHP 3, PHP 4, PHP 5)reset -- 将数组的内部指针指向第一个单元 说明 ...
- JS判断鼠标从什么方向进入一个容器
偶然将想到的一个如何判断鼠标从哪个方向进入一个容器的问题.首先想到的是给容器的四个边添加几个块,然后看鼠标进入的时候哪个块先监听到鼠标事件.不过这样麻烦太多了.google了一下找到了一个不错的解决方 ...
- Android关于buildToolVersion与CompileSdkVersion的区别
StackOverFlow中对这个问题进行了详细的讨论:http://stackoverflow.com/questions/24521017/android-gradle-buildtoolsver ...
- 正则PerlRegEx实现的批量替换指定文件中的标签
示例: 一个朋友需要而编写的标签升级更新. 速度超快,1w个文件大概4,5秒,本想加个多线程显示进度,后来想想算了 主要代码: reg.RegEx := '<' + Edit_regular1. ...
- linux安装IPython四种方法
IPython是Python的交互式Shell,提供了代码自动补完,自动缩进,高亮显示,执行Shell命令等非常有用的特性.特别是它的代码补完功能,例如:在输入zlib.之后按下Tab键,IPytho ...
- python2.7之乱码问题(直接从我的csdn上复制粘贴过来的。。。)
学习python一段时间了,一直没有写过博客.就从今天开始吧! python 3之后当然不存在乱码问题了.python 2的乱码问题有时就有点头疼了.(代码均为在windows下测试) 示例:保存为t ...
- Python脚本控制的WebDriver 常用操作 <十六> 处理对话框
下面将使用webdriver来处理一些页面跳出的对话框事件 测试用例场景 页面上弹出的对话框是自动化测试经常会遇到的一个问题.前端框架的对话框经常是div形式的,下面是一些常见的对话框操作事件: 打开 ...