String类练习题
1测试题
判断正误
public class StringExercise01 {
public static void main(String[] args) {
String a = "abc";
String b ="abc";
System.out.println(a.equals(b));
System.out.println(a==b);
}
}
String中的equal方法被重写了【查看源码】,比较的是值。
T
T
知识点:创建String对象的两种方式
2测试题
判断正误
public static void main(String[] args) {
String a = "hsp"; //a 指向 常量池的 “hsp”
String b =new String("hsp");//b 指向堆中对象
System.out.println(a.equals(b)); //T
System.out.println(a==b); //F
//b.intern() 方法返回常量池地址
System.out.println(a==b.intern()); //T //intern方法自己先查看API
System.out.println(b==b.intern()); //F
}
知识点:创建String对象的两种方式
分析:
a指向常量池的”hsp“
b指向堆中的对象,堆中对象的value指向常量池
① equals比较的是值【T】
②a==b ,ab是对象,比较的是对象的指向,一个指向的是堆中的对象,一个指向常量池【F】
③ intern 【T】
知识点:
当调用 intern 方法时,如果池已经包含一个等于此 String对象的字符串(用equals(Object)方法确定),则返回池中的字符串。否则,将此String对象添加到池中,并返回此 String对象的引用
解读:(1) b.intern()方法最终返回的是常量池的地址(对象)
④ b对象指向堆,b.intern返回的是常量池的地址【F】。
3测试题
public static void main(String[] args) {
String s1 = "hspedu"; //指向常量池”hspedu”
String s2 = "java"; //指向常量池”java”
String s4 = "java";//指向常量池”java”
String s3 = new String("java");//指向堆中对象
System.out.println(s2 == s3); // F
System.out.println(s2 == s4); //T
System.out.println(s2.equals(s3));//T
System.out.println(s1 == s2); //F
}
F
T
T
F
4测试题
public class StringExercise05 {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "hspedu";
Person p2 = new Person();
p2.name = "hspedu";
System.out.println(p1.name.equals(p2.name));//比较内容: True
System.out.println(p1.name == p2.name);
System.out.println(p1.name == "hspedu");
String s1 = new String("bcde");
String s2 = new String("bcde");
System.out.println(s1==s2);
}
}
class Person {
public String name;
}
分析:
p1.name 是String类。
p1.name = “hspedu”; 是直接赋值。所以去方法区的常量池中找
① equals比较的是内容【T】
② 【T】
③ 【T】
④ s1 s2是对象,==比较的是对象的地址,所以是【F】
StringBuffer练习题
测试题1
输出什么
public static void main(String[] args) {
String str = null;
StringBuffer sb = new StringBuffer();
sb.append(str);
System.out.println(sb.length());
System.out.println(sb);
StringBuffer sb1 = new StringBuffer(str);
System.out.println(sb1);
}
我的答案:
不知道,好模糊。。。
分析:
① String str = null;【ok】
② StringBuffer sb = new StringBuffer(); 【ok】
③ sb.append(str);需要查看源码,底层调用的是 AbstractStringBuilder 的 appendNull
④ System.out.println(sb.length()); 【输出4】
⑤ System.out.println(sb); 【输出null】
⑥ StringBuffer sb1 = new StringBuffer(str);
此时的 str =null,查看源码,super(str.length() + 16); 中会导致问题发生,会抛出空指针异常。
测试题2
输入商品名称和商品价格,要求打印效果示例,使用前面学习的方法完成:
商品名 商品价格
手机 123,564.59
要求:价格的小数点前面每三位用逗号隔开。
思路分析
1、定义一个Scanner 对象,接收用户输入的 价格(String)
2、希望使用到 StringBuffer的 insert ,需要将 String 转成 StringBuffer
3、然后使用相关方法进行字符串的处理
先完成一个最简单的实现123,564.59
找到小数点的索引,然后在该位置的前3位,插入逗号即可
// int i = sb.lastIndexOf(“.”);
// sb = sb.insert(i - 3, “,”);
上面的两步需要做一个循环处理,才是正确的
String price = "8123564.59";
StringBuffer sb = new StringBuffer(price);
for (int i = sb.lastIndexOf(".") - 3; i > 0; i -= 3) {
sb = sb.insert(i, ",");
}
System.out.println(sb);//8,123,564.59
- StringBuilder 继承 AbstractStringBuilder 类
- 实现了 Serializable,说明StringBuilder对象是可以串行化(对象可以网络传输,可以保存到文件)
- StringBuilder 是final类,不能被继承
- StringBuilder 对象的字符序列 仍然是存放在其父类AbstractStringBuilder 的char[] value;中
因此,字符序列存放在堆中- StringBuilder 的方法,没有做互斥的处理,即没有synchronized 关键字,因此在单线程的情况下使用
// StringBuilder