当前位置: 首页 > news >正文

正规网站建设找哪家/seo外包多少钱

正规网站建设找哪家,seo外包多少钱,石家庄网站推广,集团网站建设定制网站建设推荐学习最新“美团字节腾讯”一二三面问题,挑战一下你能走到哪一面?刷透近200道数据结构与算法,成功加冕“题王”,挤进梦中的字节写在前面在《阿里java开发手册(泰山版)》中,对于Java字符串的拼接有一条规则如下&…

推荐学习

  • 最新“美团+字节+腾讯”一二三面问题,挑战一下你能走到哪一面?
  • 刷透近200道数据结构与算法,成功加冕“题王”,挤进梦中的字节

写在前面

在《阿里java开发手册(泰山版)》中,对于Java字符串的拼接有一条规则如下:

22.【推荐】循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。

说明:下例中,反编译出的字节码文件显示每次循环都会 new 出一个 StringBuilder 对象,然后进行 append 操作,最后通过 toString 方法返回 String 对象,造成内存资源浪费。

反例:

String str = "start";for (int i = 0; i < 100; i++) {str = str + "hello";}

关于String、StringBuilder、StringBuffer这三个类在字符串处理中的地位不言而喻,我们用的最多的就是String 的“+”号操作符(最普遍)以及StringBuilder、StringBuffer的append()方法。

那么他们到底有什么优缺点,到底什么时候该用谁?如何才能保证字符串拼接的高效率呢?下面我们一起来了解一下。

1af4c9082a9fbd11c77acb96aa977021.png

目录

b8a1e41536c181c28e2b710ac8b7175b.png

一、有什么区别

e536a38df7a716d6706d6334f013c8d8.png

“+”号操作的字节码

“+”号操作符必须是字符串拼接最常用的一种了,没有之一。使用“+”拼接字符串,其实只是Java提供的一个语法糖。那么,我们就来解一解这个语法糖,看看他的内部原理到底是如何实现的。

还是这样一段代码。我们把他生成的字节码进行反编译,看看结果。

String str1= "唐伯虎";String str2= "点香烟";String endStr = str1+ "," + str2;

Dos反编译后的内容如下(反编译class文件的命令:javap -c 类名)。

String str1= "唐伯虎"; //唐伯虎 String str2= "点香烟"; //点香烟 String endStr = (new StringBuilder()).append(str1).append(",").append(str2).toString();

通过查看反编译以后的代码,我们可以发现,原来字符串常量在拼接过程中,是将String转成了StringBuilder后,使用其append方法进行处理的。

那么也就是说,Java中的“+”对字符串的拼接,其实现原理是使用StringBuilder.append()方法。

语法糖:语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·兰丁发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性。

二、性能比较

1. 三者在执行速度方面的比较:

152c99230a1f61f25fa7ba0c96fbd43e.gif

2. String

  • String:字符串常量
  • StringBuffer:字符串变量(无同步锁)
  • StringBuilder:字符串变量(有同步锁)

从上面的名字可以看到,String是"字符串常量",也就是不可改变的对象。源码如下

public final class String{}

对于上面这句话的理解你可能会产生这样一个疑问 ,比如这段代码:

String str = "唐伯虎"; str = str + "点香烟"; System.out.print(str); // result : "唐伯虎点香烟"

我们明明改变了String型的变量str啊,为什么说是没有改变呢?我们来看一下这张对String操作时内存变化的图:

17db655949f676fa3ffde811480d61c8.png

我们可以看到,初始String值为"唐伯虎",然后在这个字符串后面加上新的字符串"点香烟",这个过程是需要重新在栈堆内存中开辟内存空间的,最终得到了"唐伯虎点香烟"字符串也相应的需要开辟内存空间,这样短短的两个字符串,却需要开辟三次内存空间,不得不说这是对内存空间的极大浪费

f8ea69a143c74fc8d2a08abeddd1e116.png

为了应对经常性操作字符串的场景,Java提供了其他两个操作字符串的类 —— StringBuffer、StringBuilder。

他们俩均属于字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,这样就不会像String一样创建一些而外的对象进行操作了,速度自然就相对快了。

我们一般在StringBuffer、StringBuild类上的主要操作是 append 和 insert 方法,这些方法允许被重载,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。

1. StringBuilder一个可变的字符序列是JDK1.5新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。

2. 如果可能,建议优先采用StringBuilder类,因为在大多数实现中,它比 StringBuffer 要快。且两者的方法基本相同。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

String 类型和 StringBuffer、 StringBuild类型的主要性能区别其实在于 String 是不可变的对象(final), 因此在每次对 String 类型进行改变的时候其实都等同于在堆中生成了一个新的 String 对象,然后将指针指向新的 String 对象,这样不仅效率低下,而且大量浪费有限的内存空间,所以经常改变内容的字符串最好不要用 String 。因为每次生成对象都会对系统性能产生影响,特别是当内存中的无引用对象过多了以后, JVM 的 GC 开始工作,那速度是一定会相当慢的。另外当GC清理速度跟不上new String的速度时,还会导致内存溢出Error,会直接kill掉主程序!报错如下:

Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded

Exception in thread "I/O dispatcher 3797236" java.lang.OutOfMemoryError: GC overhead limit exceeded

一个特殊的例子:

String str = "This is only a" + " simple" + " test"; StringBuffer builder = new StringBuilder("This is only a").append(" simple").append(" test");

在上述例子中,经测试发现,生成str对象的速度远高于builder,而这个时候StringBuffer居然速度上根本一点都不占优势。为什么呢?

其实这是JVM的一个把戏,实际上:

String str = "This is" + " a " + "demo"; 等同于 String str = "This is a demo";

示例:

public class demo {public static void main(String[] args) {String str = "This is" + " a " + "demo";System.out.println(str);    }}

dos反编译后的内容如下(反编译class文件的命令:javap -c demo)

4bc25837a9c9352f8cd4f3f50027b3dd.png

可见,在JVM优化时,如果是多个固定字符串拼接,会将这些固定字符串进行预处理,当成一个整体的字符串,相当于仅声明一个常量,所以并不需要太多的时间。

但大家这里要注意的是,如果字符串拼接的多个元素中有其他String对象的话,速度就没那么快了,譬如:

String str2 = "陈哈哈";String str3 = "不吃";String str4 = "香菜";String str1 = str2 +str3 + str4;  // “陈哈哈不吃香菜”

或者:

String str5 = "陈哈哈"; String str6 = str5 + "不吃香菜";

这时候JVM会规规矩矩的按照原来的方式去做。

3. StringBuffer与StringBuilder的线程安全问题

fa6557dc9207225a9752b1478c210927.png

StringBuffer和StringBuilder可以算是双胞胎了,这两者的方法没有很大区别。但在线程安全性方面,StringBuffer允许多线程进行字符操作。这是因为在源代码中StringBuffer的很多方法都被关键字synchronized 修饰了,而StringBuilder没有。

有多线程编程经验的程序员应该知道synchronized。这个关键字是为线程同步机制 设定的。我简要阐述一下synchronized的含义:

每一个类对象都对应一把锁,当某个线程A调用类对象O中的synchronized方法M时,必须获得对象O的锁才能够执行M方法,否则线程A阻塞。一旦线程A开始执行M方法,将独占对象O的锁。使得其它需要调用O对象的M方法的线程阻塞。只有线程A执行完毕,释放锁后。那些阻塞线程才有机会重新调用M方法。这就是解决线程同步问题的锁机制。

了解了synchronized的含义以后,大家可能都会有这个感觉。多线程编程中StringBuffer比StringBuilder要安全多了 ,事实确实如此。如果有多个线程需要对同一个字符串缓冲区进行操作的时候,StringBuffer应该是不二选择。

注意:是不是String也不安全呢?事实上不存在这个问题,String是不可变的。线程对于堆中指定的一个String对象只能读取,无法修改。试问:还有什么不安全的呢?

三、使用总结:

1. 如果不是在循环体中进行字符串拼接的话,直接使用 String 的 “+” 就好了。

2. 单线程循环中操作大量字符串数据 → StringBuilder.append()

3. 多线程循环中操作大量字符串数据 → StringBuffer.append()

其实拼接字符串的方式还有很多种,包括String.concat()、String.join("", str1, str2)、StringUtils.join(str1, str2) 等,但在我们日常开发中最常用的就是 String 的 “+” 和 StringXXX.append()方法啦,只要掌握好这三种方式的使用场景,就基本能保证代码的高可用性了。好了,这篇文章就到这里,希望能够对你有帮助!

一张照片背后的故事

b46379fe96ce00451736c1d84b58c675.png

库尔斯克会战即将打响

所有人都在准备冲锋

只有一个人站在原地

或许他预感这一仗他很难活下去

在冲锋前的最后一刻

他亲吻了手中的十字架

作者:_陈哈哈

原文链接:https://blog.csdn.net/qq_39390545/article/details/106975969

http://www.jmfq.cn/news/4924675.html

相关文章:

  • 株洲网站建设费用/网址大全下载到桌面
  • 网站开发项目立项报告范文/如何做网络销售产品
  • 网页升级未成年人自觉离开/快速优化工具
  • 成都零起飞网站建设/网站优化北京seo
  • 肇庆网络营销外包公司/广州百度seo代理
  • 广州网站建设方案/软文写作营销
  • 湖北建设部网站官网/制作网页需要多少钱
  • 酉阳网站建设/企业软文代写
  • 服务外包下的网站开发/深圳seo推广培训
  • 上海商城网站建设公司/宁波seo网络推广报价
  • 网站如何做excel预览/对网络推广的理解
  • 新手做自己的网站教程/搜索引擎营销的特征
  • 石大网页设计与网站建设/律师推广网站排名
  • 360房产网/重庆seo网站运营
  • 网站系统名称/湖南竞价优化专业公司
  • 国外营销网站建设/软件开发自学步骤
  • 厦门外贸网站建设哪家公司大/软文代写发布
  • 沈阳健网站/考研培训
  • 在线制作app下载/搜索引擎优化指的是
  • 企业网站教程/新闻热点素材
  • 电脑如何做穿透外网网站/关键词查询网站的工具
  • 做网站上是外部连接怎么改/杭州百度快照优化公司
  • 模板网站与定制开发网站的区别/百度百家自媒体平台注册
  • 如何自建一个便宜的网站/成都网站推广经理
  • 网站风格分类有哪些/如何做企业网页
  • 上海网站建设代/sem推广外包
  • 建立网站需要多少钱 纠正错误湖南岚鸿/seo怎么做优化计划
  • 自学家装设计从哪入手/seo排名是什么意思
  • 抖音营销ppt课件/seo课程培训入门
  • 上海网站 备案查询/电话营销外包公司