首页Java基础Java源码Java框架设计模式JavaEEJava Web开发视频教程

您现在的位置:首页 >

Java基础

关注我们

优就业官方微信
优就业官方微信扫描二维码,即可与小
U亲密互动
优就业官方微博
优就业官方微博扫码关注,更有精彩活动
等你参与
  • 优就业官方QQ号

    优就业官方QQ号

    一键加好友
  • 咨询电话:( 9:00-22:00 )

    400-650-7353

为什么Java 8中不再需要StringBuilder拼接字符串

2017-12-20 17:51:12
【限时免费】年底最强一次云计算大会,看传统、社区、互联网企业如何碰撞?

在Java开发者中,字符串的拼接占用资源高往往是热议的话题.

让我们深入讨论一下为什么会占用高资源。

在Java中,字符串对象是不可变的,意思是它一旦创建,你就无法再改变它。所以在我们拼接字符串的时候,创建了一个新的字符串,旧的被垃圾回收器所标记。

如果我们处理上百万的字符串,然后,我们就会生成百万的额外字符串被垃圾回收器处理。

虚拟机底层在拼接字符串时执行了众多操作。拼接字符串最直接的点操作(dot operator)就是String#concat(String)操作。

  1. public;String;concat(String;str);{;
  2. ;;;;int;otherLen;=;str.length();;
  3. ;;;;if;(otherLen;==;0);{;
  4. ;;;;;;;;return;this;;
  5. ;;;;};
  6. ;;;;int;len;=;value.length;;
  7. ;;;;char;buf[];=;Arrays.copyOf(value,;len;+;otherLen);;
  8. ;;;;str.getChars(buf,;len);;
  9. ;;;;return;new;String(buf,;true);;
  10. };
  11. ;
  12. public;static;char[];copyOf(char[];original,;int;newLength);{;
  13. ;;;;char[];copy;=;new;char[newLength];;
  14. ;;;;System.arraycopy(original,;0,;copy,;0,;
  15. ;;;;;;;;;;;;;;;;;;;;;Math.min(original.length,;newLength));;
  16. ;;;;return;copy;;
  17. };
  18. ;
  19. void;getChars(char;dst[],;int;dstBegin);{;
  20. ;;;;System.arraycopy(value,;0,;dst,;dstBegin,;value.length);;
  21. };

你可以看到一个字符数组被创建,长度则是已有字符和拼接的字符长度之和。然后,它们的值复制到新的字符数组中。最后,用这个字符数组创建一个String对象并返回。

所以这些操作繁多,如果你计算一下,会发现是O(n^2)的复杂度。

为了解决这个问题,我们使用StringBuilder类。它就像可变的String类。拼接方法帮助我们避免不必要的复制。它拥有O(n)的复杂度,远远优于O(n^2)。

然而Java 8默认使用StringBuilder拼接字符串。

Java 8的 文档说明 :

为了提高字字符串拼接的性能,Java编译器可以使用StringBuffer类或类似技术,在使用求值表达式时,减少中间String对象的创建。

Java编译器处理这种情况:

  1. public;class;StringConcatenateDemo;{;
  2. ;;public;static;void;main(String[];args);{;
  3. ;;;;;String;str;=;"Hello;";;str;+=;"world";;
  4. ;;;};
  5. };

上面的代码会被编译成如下字节码:

  1. public;class;StringConcatenateDemo;{;
  2. ;;public;StringConcatenateDemo();;
  3. ;;;;Code:;
  4. ;;;;;;;0:;aload_0;
  5. ;;;;;;;1:;invokespecial;#1;;;;;;;;;;;;;;;;;;//;Method;java/lang/Object."":()V;
  6. ;;;;;;;4:;return;
  7. ;;public;static;void;main(java.lang.String[]);;
  8. ;;;;Code:;
  9. ;;;;;;;0:;ldc;;;;;;;;;;;#2;;;;;;;;;;;;;;;;;;//;String;Hello;
  10. ;;;;;;;2:;astore_1;
  11. ;;;;;;;3:;new;;;;;;;;;;;#3;;;;;;;;;;;;;;;;;;//;class;java/lang/StringBuilder;
  12. ;;;;;;;6:;dup;
  13. ;;;;;;;7:;invokespecial;#4;;;;;;;;;;;;;;;;;;//;Method;java/lang/StringBuilder."":()V;
  14. ;;;;;;10:;aload_1;
  15. ;;;;;;11:;invokevirtual;#5;;;;;;;;;;;;;;;;;;//;Method;java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;;
  16. ;;;;;;14:;ldc;;;;;;;;;;;#6;;;;;;;;;;;;;;;;;;//;String;world;
  17. ;;;;;;16:;invokevirtual;#5;;;;;;;;;;;;;;;;;;//;Method;java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;;
  18. ;;;;;;19:;invokevirtual;#7;;;;;;;;;;;;;;;;;;//;Method;java/lang/StringBuilder.toString:()Ljava/lang/String;;
  19. ;;;;;;22:;astore_1;
  20. ;;;;;;23:;return;
  21. };

你可以在这些字节码中看到,使用了StringBuilder。所以我们在Java 8中不再需要使用StringBuilder类。

 

免责声明:本文来源于网络,由网友提供或网络搜集,仅供个人交流学习参考使用,不涉及商业盈利目的。如有版权问题,请联系本站管理员予以更改或删除。谢谢合作!

猜你喜欢

 
 
咨询中心
优就业微信扫一扫
微信扫一扫

400-650-7353

加入官方微博