第八章学习心得

写在前面:

java的学习已经进行到第八章,即一半的知识都已经学完了。java作为我学习的第三门编程语言,有了c++和python作为奠基,学起来容易了不少,不过仍然会有力不从心的时候。这种情况多发生在学到java对文件的读写应用以及其他更”高级“的内容的时候。java有很多地方和c++、python不一样,不过也带给了我全新的感受。学完java我对其他两名语言有了更深层的理解,综合复习起来也更得心应手了。总之,接下来我还会继续努力的。

目录:

1. 借助JDK文档, 选取String与StringBuffer 、StringBuilder的常用API,并编写实例测试API的功能。      

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

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

1.借助JDK文档, 选取String与StringBuffer 、StringBuilder的常用API,并编写实例测试API的功能。

答:详见如下。

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

答:详见如下

String 不是简单类型,而是一个类,它被用来表示字符序列。 字符本身符合 Unicode 标准,其基本的初始化方式如下。

方法一:String s1='abc';这是使用字符串常量池的方式。

方法二:String s2=new String('abc');这是使用堆的方式。

不同于c++中的String类,java中,String对象是不可变的,在String类中每一个看起来会修改String对象内容的方法,实质都是创建了一个全新的String对象。

还有一个需要注意的点:

如果你的c++课稍微听了一些的话,就应该记得老师教过你如何将一个函数中对形参的影响同步到实参中。没错,可以使用指针,或者使用对象的引用。但是,在java中,不完全一样:

public class Str {
   public void changePara(String s){
     s  = s +"a";
   }
   public void invoke(){
     String s ="b";
     changePara(s);
     System.out.println(s); // 运行结果:b
   }
   public static void main(String[] str){
     Str s = new Str();
     s.invoke();   
   }
}

尽管是传引用,但通过形参引用并未改变实参指向的字符串内容。

这是学习这里的时候要格外注意的一个点。

那么为什么String被设计成了这样子的一个特点?

因为要兼顾效率和安全。这是一个折中考虑的办法。第一,照顾了字符串常量池:多个string引用可以共享同一个对象以节省空间;第二,保证了哈希码的唯一性,这样就可以缓存;第三,String是多线程安全的;第四,在网络、数据库、安全性测试中,String常作为参数进行传递。

那么问题又来了:那我要是就想实现”正宗的String“该怎么办?

那么你可以使用StringBuffer。这应该是”你期望的“那种String。

StringBuffer对象的值是可变的,对字符串的增加、插入、修改、删除等操作比String高效(不需多次创建新的对象)。

不过可以证明,StringBuffer不是高效的。下面会陆续提到这个问题。

为了解决StringBuffer不够高效的问题,JDK5 引入了StringBuilder,其与StringBuffer的 API兼容, 性能比StringBuffer更高,但不是线程安全的。那么具体高效在哪呢?下面我们就来看看这个问题。

假设我现在有这样一个需求:我需要一个字符串,前面1000个是a,后面1000个是b。现在,我希望尽快的在屏幕上看到这个字符串。

显然使用暴力的方法一个一个按不见得比使用代码更快,而且还容易出错。

于是我们决定使用代码解决这个问题。

鉴于问题性质,我只考虑a的情况。

采用String字符串拼接:

for(int i=0; i<10000;i++){    s = s + “a” ;  //编译器会进行优化,但此种写法仍然效率低下,循环体内每次                     需要产生StringBuilder对象  

采用StringBuilder字符串拼接:

StringBuilder st = new StringBuilder("a"); //效率较高,只需新建一个对象 for(int i=0; i<10000;i++){     st.append(“b"); }

这样就可以看出区别了。

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

答:为了提高效率

还是接着2的例子来讲。采用第一种,那么就要新建1000个对象,而每次新建一个对象都是有开销的,所以不是很高效。采用第二种,就只新建一个初始对象即可。

不难发现,第二种方法中,当前一步用上了上一步的结果,是”站在他的肩膀上“,所以只需要做到额外的内容即可。

这就像算法中经典的求和算法一样。我先给你一串数字,然后我会问你很多很多次如下性质的问题:这串数字前m个数字和前n个数字的和的差是多少?最简单暴力的方法是逐次模拟。你问我一次问题,我就把结果从头到尾算一遍,然后得出答案,再通通忘掉。下次再问的时候,再从头到尾算一遍,再忘掉。。。如此,就把大量的时间和空间都浪费掉了。不如我们只算一遍,但是把结果记下来:前1个数的和是多少,前2个数的和是多少,,,前n个,前m个数的和是多少。你问我一次,我就去查表,然后马上给你结果。这样就节省了大量的时间。根本原因还是在于,后一步的进行很好的运用到了前一步的结果。

回到题目,如果使用+进行拼接,就没有做到:”后一步的进行很好的运用到了前一步的结果“。事实上这个问题前后是有关联、可以逐步推进的。所以,自然不建议这样做。

好啦,第八章就到这里吧,晚安家人们~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值