使用String.subString()方法的时候注意内存溢出的问题

  public static void testH() {
List<String> strings = new ArrayList<String>();
for (int i = ; i < ; i++) {
HugeStr h = new HugeStr();
// ImprovedHugeStr h = new ImprovedHugeStr();
strings.add(h.getSubString(, ));
}
} static class HugeStr {
private String str = new String(new char[]); String getSubString(int begin, int end) {
return str.substring(begin, end);        //会内存溢出
}
} static class ImprovedHugeStr {
private String str = new String(new char[]); String getSubString(int begin, int end) {
return new String(str.substring(begin, end)); //返回的新String,没有溢出
}
}

三种分隔字符串的方法,split()简单性能最差,StringTokenizer性能次之,自定义的方法性能最好但是可读性太低。建议StringTokenizer

  static String initOrgStr() {
StringBuffer sb = new StringBuffer();
for (int i = ; i < ; i++) {
sb.append(i);
sb.append(":");
}
return sb.toString();
} static void normalSplidTest() {
String orgStr = initOrgStr();
for (int i = ; i < ; i++) {
orgStr.split(";");
}
} static void stringTokenizerTest() {
String orgStr = initOrgStr();
StringTokenizer st = new StringTokenizer(orgStr, ":");
for (int i = ; i < ; i++) {
while (st.hasMoreElements()) {
st.nextElement(); }
st = new StringTokenizer(orgStr, ":");
}
} static void selfSplidTest() {
String orgStr = initOrgStr();
String tmp = orgStr;
for (int i = ; i < ; i++) {
while (true) {
String splitStr = null;
int j = tmp.indexOf(":");
if (j < ) {
break;
}
splitStr = tmp.substring(, j);
tmp = tmp.substring(j + );
} tmp = orgStr;
}
}

String的charAt()和jindexOf()性能都特别的好,charAt连用甚至比startWith()、endWith()还快。

StringBuilder和StringBuffer:String在使用 “+”的时候,如果 + 的是具体的字符串,也就是编译期可知的,那么在编译期就已经完成了优化,只有最后的一个大字符串。

String result = "String" + "and" + "String"
// 反编译后只有这一个大字符串
String result = "StringandString"

StringBuilder.append还是会按照代码的顺序执行,依次append。

StringBuilder sb = 呢我StringBuilder()
sb.append("String");
sb.append("and");
sb.append("String");

如果编译期不可知,最终也是用StringBuilder进行优化。

String str1 = "String";
String str2 = "and";
String str3 = "String";
String result = str1 + str2 + str3;
//反编译
String s = (new StringBuilder(String.valueOf(str1))).append(str2).append(str3).toString();

如果超大的字符串,String的 + ,被反编译StringBuilder实现,但是每次都会生成新的 StringBuilder。String的 + 最差,concat次之,StringBuilder最好。

  static void hugeStr() {
String s = "";
for (int i = ; i < ; i++) {
s += i;
} String result = "";
for (int i = ; i < ; i++) {
result = result.concat(String.valueOf(i));
} StringBuilder sb = new StringBuilder();
for (int i = ; i < ; i++) {
sb.append(i);
}
}

StringBuffer线程安全,StringBuilder线程不安全。如果单线程StringBuilder会比StringBuffer好些。

如果知道字符串会有多大,在初始化的时候给定值,性能会更好。

public StringBuilder(int capacity)
public StringBuffer(int capacity)

ArrayList、Vector:Vector线程安全。其他几乎一样。LinkedList使用双向连表。

如果list对象需要经常在任意位置插入元素,可以考虑使用LinkList代替ArrayList。但是LinkList从中间删除元素会特别耗时,它是遍历所有,找到具体的位置,在移除。
ArrayList和LinkList三种遍历方法。foreach和迭代器两种差不多,for循环LinkedList不要用,慢到你无法想象。迭代器会更好些,foreach最终也会解析成迭代器还多了一步没用的复制语句所以性能差一些。

  static void eachList(List<String> list) {
String tmp;
for (String s : list) {
tmp = s;
} for (Iterator<String> it = list.iterator(); it.hasNext();) {
tmp = it.next();
} int size = list.size();
for (int i = ; i < size; i++) {
tmp = list.get(i);
}
}

Map

HashMap:它最重要的就是原理了。理解原理。
LinkedHashMap:在HashMap的基础上加了一个链表存放顺序。accessOrder为true按照元素最后访问时间顺序,为false按照存入顺序,默认false。

public LinkedHashMap(int initialCapacity, folat loadFactor, boolean accessOrder)

可以修改accessOrder看看顺序

  static void mapTest() {
LinkedHashMap<Integer, String> map = new LinkedHashMap<>(, 0.75F, false);
map.put(, "k");
map.put(, "f");
map.put(, "z");
map.put(, "z");
map.put(, "z");
map.put(, "z");
map.put(, "z");
map.put(, "z");
map.get();
map.get();
map.get();
for (Iterator<Integer> iterator = map.keySet().iterator(); iterator.hasNext();) {
Integer key = (Integer) iterator.next();
System.out.println(key);
}
}

TreeMap:这个就nb了,根据key排序。想使用这个或者在 new TreeMap(Comparator<? super K> comparator)创建的时候指定Comparator,或者key实现了Comparable接口。

  static void treeMapTest() {
Map<Integer, String> map = new TreeMap<>();
map.put(, "k");
map.put(, "f");
map.put(, "z");
map.put(, "z");
map.put(, "z");
map.put(, "z");
map.put(, "z");
map.put(, "z");
for (Iterator<Integer> iterator = map.keySet().iterator(); iterator.hasNext();) {
Integer key = (Integer) iterator.next();
System.out.println(key);
} Map map2 = ((TreeMap) map).subMap(, );
System.out.println("get the key more than or equal 1 and less than 4");
for (Iterator<Integer> iterator = map2.keySet().iterator(); iterator.hasNext();) {
Integer key = (Integer) iterator.next();
System.out.println(key);
}
// 小于2的
Map map3 = ((TreeMap) map).headMap();
// 大于2的
Map map4 = ((TreeMap) map).tailMap();
}

从性能角度分析一下String,List,Map的更多相关文章

  1. list 、set 、map 粗浅性能对比分析

    list .set .map 粗浅性能对比分析   不知道有多少同学和我一样,工作五年了还没有仔细看过list.set的源码,一直停留在老师教导的:"LinkedList插入性能比Array ...

  2. 从系统的角度分析影响程序执行性能的因素——SA20225205 黄兴宇

    实验总结分析报告:从系统的角度分析影响程序执行性能的因素 1.请您根据本课程所学内容总结梳理出一个精简的Linux系统概念模型,最大程度统摄整顿本课程及相关的知识信息,模型应该是逻辑上可以运转的.自洽 ...

  3. 第九节:从源码的角度分析MVC中的一些特性及其用法

    一. 前世今生 乍眼一看,该标题写的有点煽情,最近也是在不断反思,怎么能把博客写好,让人能读下去,通俗易懂,深入浅出. 接下来几个章节都是围绕框架本身提供特性展开,有MVC程序集提供的,也有其它程序集 ...

  4. 从虚拟机指令执行的角度分析JAVA中多态的实现原理

    从虚拟机指令执行的角度分析JAVA中多态的实现原理 前几天突然被一个"家伙"问了几个问题,其中一个是:JAVA中的多态的实现原理是什么? 我一想,这肯定不是从语法的角度来阐释多态吧 ...

  5. Linux性能监控分析命令(五)—free命令介绍

    性能监控分析的命令包括如下:1.vmstat2.sar3.iostat4.top5.free6.uptime7.netstat8.ps9.strace10.lsof 命令介绍:free命令是监控Lin ...

  6. Linux性能监控分析命令(四)—top命令介绍

    性能监控分析的命令包括如下: 1.vmstat 2.sar 3.iostat 4.top 5.free 6.uptime 7.netstat 8.ps 9.strace 10.lsof ======= ...

  7. 从程序员的角度分析微信小程序(编程语言:用到什么学什么)

    从程序员的角度分析微信小程序(编程语言:用到什么学什么) 一.总结 一句话总结:微信小程序原理就是用JS调用底层native组件,和React Native非常类似.(需要时,用到时再学) 1.选择语 ...

  8. 性能测试——记XX银行保全项目性能问题分析优化

    记XX银行保全项目性能问题分析优化 数据库问题也许是大部分性能问题的关注点,但是JAVA应用与数据库交互的关节,JDBC 就像是我们人体的上半身跟下半身的腰椎,支持上半身,协调下半身运动的重要支撑点. ...

  9. windows系统与SQL SERVER 2008数据库服务性能监控分析简要

    软件系统性能测试体系流程介绍之windows系统与SQL SERVER 2008数据库服务性能监控分析简要 目前大部分测试人员对操作系统资源.中间件.数据库等性能监控分析都是各自分析各自的监控指标方式 ...

随机推荐

  1. [转]Tomcat工作原理详解

    一.Tomcat背景 自从JSP发布之后,推出了各式各样的JSP引擎.Apache Group在完成GNUJSP1.0的开发以后,开始考虑在SUN的JSWDK基础上开发一个可以直接提供Web服务的JS ...

  2. asp.net中UpdatePanel数据加载成功后回调

    //添加UpdatePanel加载成功后执行的js方法 Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(onPageLoade ...

  3. Mysql 创建权限较小的用户(只对特定数据库有操作权限)

    项目开发过程中,因为root的权限太大,可能对其他数据库造成修改.故创建一权限较小的用户,使其只能对特定的数据库操作,以保证数据安全. 主要语句如下: grant all on bos19.* to ...

  4. java中替换双引号 Java问题通用解决代码 Java问题通用解决代码

    http://blog.csdn.net/newhappy2008/article/details/4785263 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...

  5. python测试网页是否能正常登陆

    #!/usr/bin/python #encoding:utf-8 ##实现网页的登陆检查 import HTMLParser import urlparse import cookielib imp ...

  6. nginx 使用ngx_cache_purge清除缓存

    location ~ ^/myclear(/.*) { allow 10.0.0.0/8; allow 10.28.100.0/24; allow 127.0.0.1; deny all;   pro ...

  7. Spring学习二----------IOC及Bean容器

    © 版权声明:本文为博主原创文章,转载请注明出处 接口 用于沟通的中介物的抽象化 实体把自己提供给外界的一种抽象化说明,用以由内部操作分离出外部沟通方法,使其能被修改内部而不影响外界其他实体与其交互的 ...

  8. 查看/设置MySQL数据库的事务隔离级别

    查看InnoDB存储引擎 系统级的隔离级别 和 会话级的隔离级别: mysql> select @@global.tx_isolation,@@tx_isolation; +---------- ...

  9. Sqlserver建立Oracle的鏈接服務器

    --建立数据库链接服务器 EXEC sp_addlinkedserver @server =N'TestOracle', --要创建的链接服务器别名 @srvproduct=N'Oracle', -- ...

  10. MVC进阶学习--View和Controller之间的数据传递(一)

    1.使用ViewData ViewData 的是ControllerBase 的一个属性,是一个数据字典类型的,其实现代码如(这段代码来自asp.net MVC开源项目中源码)下: Code   1  ...