问答题
1.借助JDK,选取几个String与StringBuffer、StringBuilder的常用API,并编写实例测试API的功能。
public class text1
{
public static void main(String[] args)
{
String s="accdedcba" ;
System.out.println("字符串的长度为:"+s.length());
System.out.println("字符c第一次出现的位置:"+s.indexOf('c'));
System.out.println("字符c最后一次出现的位置:"+s.lastIndexOf('c'));
}
}
public class text1
{
public static void main(String[] args)
{
String str="abcd";
System.out.println("将字符串转换为字符数组后的结果");
char[] charArray=str.toCharArray();
for(int i=0;i<str.length();i++)
{
if(i!=str.length()-1)
{
System.out.print(charArray[i]+",");
}
else
{
System.out.println(charArray[i]);
}
}
System.out.println("将int值转换为string类型之后的结果:"+String.valueOf(12));
System.out.println("将字符串转换为大写之后的结果:"+str.toUpperCase());
}
}
public class text1
{
public static void main(String[] args)
{
String s1="STring";
String s2="Str";
System.out.println("判断是否以str开头"+s1.startsWith("Str"));
System.out.println("判断是否一ng结尾"+s1.endsWith("ng"));
System.out.println("判断是否包含字符串"+s1.contains("tri"));
System.out.println("判断字符串是否为空:"+s1.isEmpty());
System.out.println("判断字符串是否相等:"+s1.equals(s2));
}
}
StringBuffer sb=new StringBuffer();
StringBuffer s1=sb.append(4).append(false).append("haha");
sb.insert(1,"qwe");
System.out.println(sb==s1);
System.out.println(sb);
StringBuffer sb=new StringBuffer("abce");
sb.replace(2,3,"nab");//包含头不包含尾
sb.setCharAt(2,'q');
System.out.println(sb.toString());
StringBuffer sb=new StringBuffer("abce");
sb.delete(0,sb.length());//清空缓冲区
sb.deleteCharAt(2);
System.out.println(sb.toString());
2.请简述String,StringBuffer,StringBulider三者之间的共同点与区别,应该分别在何种场景下使用?
共同点:
StringBuilder 与 StringBuffer 有公共父类AbstractStringBuilder(抽象类)。
StringBuilder、 StringBuffer 的方法都会调用 AbstractStringBuilder 中的公共方法,如super.append(…)。 只是 StringBuffer 会在方法上加 synchronized关键字,进行同步。
不同点:
String:字符串常量,在修改时不会改变自身;若修改,等于重新生成新的字符串对象。对象定义后不可变,线程安全。
StringBuffer:在修改时会改变对象自身,每次操作都是对 StringBuffer 对象本身进行修改,不是生成新的对 象;使用场景:对字符串经常改变情况下,主要方法: append(), insert()等。是线程安全的(对调用方法加入同步锁),执行效率较慢,适用于多线程下操作字符串缓冲区 大量数据。
StringBuilder:是线程不安全的,适用于单线程下操作字符串缓冲区大量数据。
String :操作少量的数据
StringBuilder:单线程操作大量数据,多线程操作大量数据
StringBuffer:多线程操作大量数据
3.为什么不建议在for循环中使用“+”进行字符串拼接?
例:
long t1 = System.currentTimeMillis();
String str = "hollis";
for (int i = 0; i < 50000; i++) {
String s = String.valueOf(i);
str += s;
}
long t2 = System.currentTimeMillis();
System.out.println("+ cost:" + (t2 - t1));
反编译后:
long t1 = System.currentTimeMillis();
String str = "hollis";
for(int i = 0; i < 50000; i++)
{
String s = String.valueOf(i);
str = (new StringBuilder()).append(str).append(s).toString();
}
long t2 = System.currentTimeMillis();
System.out.println((new StringBuilder()).append("+ cost:").append(t2 - t1).toString());
反编译后的代码,在for循环中,每次都是new了一个StringBuilder,然后再把String转成StringBuilder,再进行append。频繁的新建对象要耗费很多时间了,频繁的创建对象,还会造成内存资源的浪费,大大降低了效率。所以,在循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。而不要使用+。
4.什么是字符串的编码与解码?请举例说明。
编码:规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储,这个规定就叫做“编码” 平常我们所说的“字符集”,比如:GB2312, GBK, JIS 等。
把unicode字符集转为本地字符集的过程叫编码,反之叫解码。
例:
1.将字符串转换成byte数组再恢复:
byte[] getBytes(String charsetName)
String(byte[] bytes, String charsetName)或getBytes()
String(byte[] bytes)
2.使用String sun.misc.BASE64Encode.encode(byte[] b):
byte[] String sun.misc.BASE64Decode.decodeBuffer(String str)将字符串转换成byte[],再转换成ASCII码;恢复时做逆操作。在字符串转换成byte[]时,尽量用byte[] getBytes(String charsetName)方法,解码时也用相同的charsetName做参数,如果都不charsetName可能会导致一些中文字符不能正确解码。
3.使用java.net.URLEncoder类和java.net.URLDecoder类
它有static方法将字符串转换成‘pplication/x-www-form-urlencoded’格式便于在网络中传播。形如‘%20%35’。