Java第8章作业:Java常用类库与工具

第一题:借助JDK, 选取几个String与StringBuffer 、StringBuilder的常用API,并编写实例测试API的功能。

  1. public char charAt(int index)
    该方法返回字符串中指定位置的字符,index的范围是0到length()-1。

    package string;
    
    public class Str {
        public static void main(String[]str){
            String s = new String("String");
            System.out.println(s.charAt(1)); // return t
    
            StringBuffer sb = new StringBuffer("StringBuffer");
            System.out.println(sb.charAt(2)); // return r
    
            StringBuilder ss = new StringBuilder("StringBuffer");
            System.out.println(ss.charAt(3)); // return i
        }
    }  
      
    
  2. public int indexOf(String str)
    该方法接收一个String对象参数并返回该第一次出现该对象的下标,若参数不在对象中则返回-1。

    package string;
    
    public class Str {
        public static void main(String[]str){
            String s = new String("String");
            System.out.println(s.indexOf("ing")); // return 3
    
            StringBuffer sb = new StringBuffer("StringBuffer");
            System.out.println(sb.indexOf("Buffer")); // return 6
            System.out.println(sb.indexOf("buffer")); // return -1
    
            StringBuilder ss = new StringBuilder("StringBuffer");
            System.out.println(ss.indexOf("Buffer")); // return 6
            System.out.println(ss.indexOf("buffer")); // return -1
        }
    }  
    
  3. substring方法
    用法为:public String substring(int beginIndex)
    public String substring(int beginIndex, int endIndex)两种
    第一种用法接收一个数字,取从beginIndex开始到该字符串结尾的子字符串;第二种用法接收两个数字,取从beginIndex开始到endIndex结尾的子字符串,不包括下标为endIndex的字符。
    示例如下:

    package string;
    
    public class Str {
        public static void main(String[]str){
            String s = new String("String");
            System.out.println(s.substring(0,3)); // return Str
            System.out.println(s.substring(2)); //  return ring, equal to s.subtring(2,length)
    
            StringBuffer sb = new StringBuffer("StringBuffer");
            System.out.println(sb.substring(0,3)); // return Str
    
            StringBuilder ss = new StringBuilder("StringBuffer");
            System.out.println(ss.substring(0,3)); // return Str
        }
    }    
    

第二题:请简述String,StringBuffer,StringBuilder三者之间的共同点与区别,应该分别在何种场景下使用?

共同点

  1. 都是字符数组的封装,有许多与字符串相关的方法,使用起来非常方便;
  2. 可以自动检测数组越界等异常情况,可以动态分配字符数组内存;

区别

  1. String对象的内容是不可变的,对String对象的更改操作会建立一个新的对象,原有的对象不会发生变化;而StringBufferStringBuilder里面的内容都是可变的,对其内容的操作会在原有对象基础上进行;
  2. 性能方面,由于String对象是不可变的,在两个String对象进行字符串连接(使用“+”符号)时会新建String对象,导致运行速度变慢,而StringBufferStringBuilder对象则可以通过append方法进行字符串连接,无需建立新对象,性能更快;
  3. 此外,StringBufferthread-safe的,因为其含有方法是被synchronized修饰的,具有原子性,而StringBuilder不是thread-safeStringBuilder的方法没有被synchronized修饰。

第三题:为什么不建议在for循环中使用“+”进行字符串拼接?

1首先介绍一下使用“+”进行字符串拼接会发生什么事

请注意,“+”符号只适用于String对象,该操作符无法对StringBufferStringBuilder对象进行拼接。

请看以下例子:

String s = "ABC";
s = s + "dd";

在上面的例子中,我定义了一个String对象s,其内容是"ABC",然后使用操作符“+”将s与字符串"dd"进行拼接,在这个过程中发生了以下几件事:

  1. 首先将String对象s转化为StringBuilder对象(确实是StringBuilder,而不是StringBuffer,不信可以去debug看看,我认为之所以用StringBuilder是因为它比StringBuffer效率更高),这里调用的是StringBuilder(String str)构造方法,此时s的内容是"ABC";
  2. 然后会通过StringBuilderappend方法将字符串"dd"加入到对象ssStringBuilder对象)中,s的内容是"ABCdd";
  3. 最后调用对象s(此时s仍然是StringBuilder对象)的toString方法将s转成String类型,然后将新的内容赋给对象引用s(这里指的是String类型的s),但此时已经重新生成了一个String对象(因为String类型是不可变的),其内容是"ABCdd",而原来s所指向的String对象仍然存在,只是不与对象引用s所关联了;
    总结一下,使用“+”进行字符串拼接的语句s = s + "dd";可以分为以下3个步骤:
StringBuilder stmp = new StringBuilder(s);
stmp.append("dd");
s = stmp.toString();
2 为什么不建议在for循环中使用“+”进行字符串拼接?

回到正题,前面探讨了使用“+”进行字符串拼接所发生的事情,那么这个问题就很容易解释了。
在使用“+”进行字符串串接的时候,会首先生成一个StringBuilder对象,然后将后面的字符串加入StringBuilder对象,最后返回String类型时会生成一个String对象,因此一个串接过程生成了2个对象,如果在循环里面使用这种方式进行串接,会生成非常多的对象,导致性能极差!因此在对多个字符串进行串接时最好使用StringBuilderStringBuffer的append方法。

第四题:什么是字符串的编码与解码?请举例说明。

Java中采用的字符集是Unicode字符集,因此对于Java来说,将Unicode字符集转为本地字符集(即自己电脑上的字符集,如GB2312GBK)的过程称为编码;将本地字符集转为Unicode字符集的过程称为解码。

对于字符集编码方式的解读,可以看ASCII,Unicode和UTF-8终于找到一个能完全搞清楚的文章了

下面举例说明将“中文”二字从Unicode字符集转为GB2312UTF-8字符集:

package string;

import java.io.*;

public class CharCode {
    public static void printByteArray(String msg, byte[] t) {
        System.out.println(msg + "length is " + t.length + "****************"); // length是字节个数
        for (int i = 0; i < t.length; i++) {
            System.out.println(Integer.toHexString(t[i])); // toHexString是将数字转为16进制表示
        }
    }

    public static void printCharArray(String msg, char[] c) {
        System.out.println(msg + "length is " + c.length + "****************"); 
        for (int i = 0; i < c.length; i++) {
            System.out.println(Integer.toHexString(c[i]));
        }
    }

    public static void main(String[] args){
        try{
            String str = "中文";
            System.out.println(str);
            printCharArray("unicode: ",str.toCharArray()); //unicode字符集中对"中文"二字的对应代码
            printByteArray("unicode: ",str.getBytes());

            byte[] b;
            b = str.getBytes("UTF-8"); //编码:转为本地字符集GBK2312对应的代码
            printByteArray("UTF-8: ",b);

            b = str.getBytes("GB2312"); //编码:转为本地字符集GB2312对应的代码
            printByteArray("GB2312: ",b);

        }
        catch(UnsupportedEncodingException e){
            System.out.println("没有相应的字符集!"); } 
    }
}

输出如下:

中文
unicode: length is 2****************
4e2d
6587
unicode: length is 6****************
ffffffe4
ffffffb8
ffffffad
ffffffe6
ffffff96
ffffff87
UTF-8: length is 6****************
ffffffe4
ffffffb8
ffffffad
ffffffe6
ffffff96
ffffff87
GB2312: length is 4****************
ffffffd6
ffffffd0
ffffffce
ffffffc4

可以看到,“中”的Unicode编码是4e2d(16进制数),“文”的Unicode编码是6587(16进制),而它们在UnicodeUTF-8字符集中均占用3个字节(length是6),在GB2312字符集中各占用2个字节(length是4)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值