使用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. unsigned int与int相加问题

    作者 : 卿笃军 一道unsigned int与int类型的相加题目.引发了我对这个问题的思考. 首先要明确两个问题: 问题一. unsigned int 和 int究竟哪个能表达出来的数上限大呢? ...

  2. C# 写日志到文件

    C# 写日志到文件 using System;using System.Collections.Generic;using System.Text;using System.Windows.Forms ...

  3. hdu 5348 MZL&#39;s endless loop

    给一个无向图(事实上是有向的.可是没有指定边的方向),你须要指定边的方向,使得每一个点入度和出度相差不超过1. 事实上就是找很多条路径.合起来能走完这个图..先统计各个顶点的度.度为奇数必是起点或终点 ...

  4. Mac下配置mnmp环境

    虽然比较喜欢玩下新语言, 但是php还是常会用到的. lnmp很多人都听过, 但是不能用在Mac上面, 另外还有个mnpp但在osx 10.8.3下面跑不起来.所以自己手动一步步安装, 整理了方便安装 ...

  5. Android studio 百度地图开发(3)地图导航

    Android studio 百度地图开发(3)地图导航 email:chentravelling@163.com 开发环境:win7 64位,Android Studio,请注意是Android S ...

  6. use-svn-cmd(Linux)

    SVN是Subversion的简称,是一个开放源代码的版本控制系统,它采用了分支管理系统,是一个跨平台的软件,支持大多数常见的操作系统. svn命令行使用: 1.查看svn所支持的全部命令 $ svn ...

  7. 微软2016校园招聘在线笔试第二场 题目1 : Lucky Substrings

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 A string s is LUCKY if and only if the number of different ch ...

  8. homebrew可以管理众多开源软件的安装和卸载

    通过homebrew可以管理众多开源软件的安装和卸载. 参考https://github.com/mxcl/homebrew/wiki 1. 安装: ruby -e "$(curl -fsS ...

  9. SO_KEEPALIVE

    if tcp_keepalive: # 启用KeepAlive选项 sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # TCP_K ...

  10. (2) yum源配置-163

    1.获取yum源文件 登录http://mirrors.163.com/.help/centos.html,查看CentOS6的链接地址(右键点击“CentOS6”,选择复制链接地址),链接地址为:h ...