`

Java 面试中关于截取字符串例子

阅读更多
面试中,关于字符串问题,出现几率比较高的两个问题 


第一个问题: 



public static void main(String[] args)  

{ 

String s = new String("abc"); //执行到这一行时,创建了几个对象? 

String s1 = "abc"; //执行到这一行时,创建了几个对象? 

String s2 = new String("abc"); //执行到这一行时,创建了几个对象? 


System.out.println(s == s1); //输出结果是什么? 

System.out.println(s == s2); //输出结果是什么? 

System.out.println(s2 == s1); //输出结果是什么? 

} 


解答: 

(1) 执行第一行的时候创建两个对象。为什么是两个对象,我们先来分析下。应为String类型是一个特殊类型,因为是final 来存储字符串对象。所以一旦创建String类型的字符串,就不能更改。关于用常量来声明字符串对象就要不得不说String pool 的概念(关于String pool 的概念,我在下一章进行详细介绍,这里不多说了。)。在这里记住一点凡是""声明的字符串对象都存储在String pool池中。 


那么在执行第一句中("abc")声明的对象就存储在String pool中,这是声明第一个对象。 

当new Strring时,又产生一个对象,只不过这个对象是存放在内存heap(堆中)。还要记住一点只要有new 关键字就会产生一个新的对象,这是声明的第二个对象。 

答案:执行第一行产生2个对象。 


(2)当执行第二行的时候,我说过凡是用""声明的字符串对象就会存储到String pool池中。 

但这里需要记住的是String pool池中,不会存储相同的字符串对象,每当用""声明字符串对象前,都会先检查String pool池中,是否存在相同的字符串对象。如果存在相同的字符串对象,则返回该对象。如果没有该字符串对象,则把该对象加入String pool池中。因为执行第一行时,已经把"abc"字符串放到String pool池中,所以当执行String s1="abc";已经发现String pool池中有abc字符串,则不会创建,而是直接返回该对象。所以这行并没有创建对象 


答案:执行第二行产生0个对象。 


(3)执行第三行时,我说过"abc"对象已经存在String pool池中,则不会创建。记住String pool池中不会存储相同字符串对象。只要有new 的地方就会在heap(堆)中产生一个新的对象。 

答案:执行第三行产生1个对象。 


(4)因为s引用的对象是存储在String pool池中,而s1引用的对象是存储在heap(堆)中,引用的不是同一个对象。所以执行System.out.println(s == s1); 


答案:结果为false。 


(5)因为s引用的对象是存储在String pool池中,而s2引用的对象是存储在heap(堆)中,引用的不是同一个对象。所以执行System.out.println(s == s2); 


答案:结果为false。 


(6)虽然s1和s2引用的对象都存储在heap(堆)中,但他们的内存地址不相同,所以不是同一个对象,这是因为使用new 关键字创建对象时,会新开辟一块内存空间来存放对象。所以用new 创建同一个对象,永远都不会相同。所以执行System.out.println(s2 == s1); 


答案:结果为false。 




----------------------------------------------------------------------------- 



下面是一个关于字符串的机试问题: 


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




样例: 


/* 

* 按照指定字节,截取子字符串函数 

* @param str 要截取的字符串 

* @param len 要截取的字节数 

* @return String 截取后子字符串 

*/ 

public static String splitString(String str,int len) 

{ 

if(str==null||str.equals("")) 

{ 

return ""; 

} 

byte[] b=str.getBytes(); 

String subString=null; 

if(b.length<len || len<0) 

{ 

return str; 

} 

if(len>1) 

{ 

if(b[len]<0) 

{ 

subString=new String(b,0,--len); 

} 

else 

{ 

subString=new String(b,0,len); 


} 

} 

else 

{ 

if(len==1) 

{ 

if(b[len]<0) 

{ 

subString=new String(b,0,++len); 

} 

else 

{ 

subString=new String(b,0,len); 

} 


} 

} 

return subString; 

} 








下面提供两个按照指定编码截取字符串 



第一种按照:Unicode 编码方式来产生字节数组 


String str="我爱java"; 

String s=str.getBytes("Unicode"); 


这种方式产生的字节数组,字节数组的前两个字节为标志位,如byte[0]=-1,byte[1]=-2。从第三位开始才是真正的字符串。在Unicode 编码下,汉字、英文、数字都是两个字节。而英文和数字,第一个字节是相应的ASCII码,第二个字节是0.而汉字两个字节都大于0. 



这种方法每个字符都是两个字节: 



/* 

* 按照双字节,截取指定函数 

* @param str 要截取的字符串 

* @param len 要截取的长度 

* @return string 截取后的字符串 

*/ 

public static String mySubString(String str,int len) throws UnsupportedEncodingException 

{ 

/*首先把目标字符串分解成Unicode编码的字节数组, 

* 这样的目的是每个字符都变成两个字节,在根据 

* 英文和数字字符在Unicode编码下,第一个字节 

* 是相应的ASCII码,第二个字节为0的特征,来进行 

* 计算 

*/ 

int pos=len+1; 

byte[] b=str.getBytes("Unicode"); 



if(b[len]==0) 

{ 

return new String(b,0,len+1,"Unicode"); 

} 


if(b[len]!=0) 

{ 

if(b[len+1]!=0) 

{ 

if((len%2!=0)) 

{ 

return new String(b,0,len+1,"Unicode"); 

} 

else 

{ 

return new String(b,0,len+2,"Unicode"); 

} 

} 

else 

{ 

return new String(b,0,len+2,"Unicode"); 

} 

} 

return null; 


} 




------------------------------------------------------------------------------- 


第二种按照:GBK编码方式产生字节数组 


String str="我爱java"; 

String s=str.getBytes("GBK"); 



这种方式产生的字节数组,汉字是两个字节,英文和数字是一个字节。而汉字两个字节都小于0.而英文和数字产生的字节都是相对应的ASCII码。如 a 对应 97。 


样例: 

/* 

* 目标字符串中截取指定字节函数 

* @param str 要截取的字符串 

* @param len 要截取的长度 

* @return string 截取后的字符串 

*/ 

public static String mySubString(String str,int len,String symbol) throws UnsupportedEncodingException 

{ 

if(str==null||str.equals("")) 

{ 

return ""; 

} 

int count=0; 

byte[] b=str.getBytes("GBK"); 

if(b.length<len) 

return str; 

for(int i=0;i<b.length;i++) 

{ 

if(b<0) 

{ 

count++; 

} 

} 

if(count%2==0) 

{ 

return new String(b,0,len,"GBK")+symbol; 

} 

else 

{ 

return new String(b,0,len-1,"GBK")+symbol; 

} 



} 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics