使用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. 【BIEE】BI Publisher下拉菜单设置

    在使用BIEE的过程中,通常会有需要根据下拉菜单所选内容进行数据展示,如下图所示: 设置参数 进入数据模型编辑界面→参数 新增参数,P_DATADATE为示例参数 参数赋值 同时点击"值列表 ...

  2. ROS库生成和调用

      参考资料: 生成.so文件:http://blog.csdn.net/u013243710/article/details/35795841 调用.so文件:http://blog.csdn.ne ...

  3. Spring MVC 学习笔记 spring mvc Schema-based configuration

    Spring mvc 目前支持5个tag,分别是 mvc:annotation-driven,mvc:interceptors,mvc:view-controller, mvc:resources和m ...

  4. android实现免费短信验证

    代码地址如下:http://www.demodashi.com/demo/12541.html 前言 获取短信验证码的的第三方很多,今天介绍一个获取短信验证码的demo,它有以下优势 短信到达率几乎1 ...

  5. [1-6] 把时间当做朋友(李笑来)Chapter 6 【更多思考】 摘录

    记住,你不可能百分之百地有效率,至少不可能总是百分之百地有效率. 他们的效率很差.根源在于,他们其实只做简单的事情,而回避那些有难度的工作. 好像丢钱包的人都不是“故意”丢的一样,办事拖拉的人大多并非 ...

  6. java 乱码问题解决思路

    "编码一致的条件下,在处理运行正常的情况下,是不会出现乱码的",记住这句金言. 如上所说,如果编码一致是不会出现这种乱码问题,所以解决办法就是仔细再仔细的检查所设置的编码是否是一致 ...

  7. window 服务(二)

    接Window服务(一) ServiceController方法调用 public partial class Service1 : ServiceBase { public Service1() { ...

  8. es快照和备份

    注册前要注意配置文件加上 path.repo: ["/data/es_backup"] 然后重启es 不然会报错doesn't match any of the locations ...

  9. ros之串口通信---imu

    1.sudo apt-get install ros-kinetic-rosserial 或者sudo git clonegit://github.com/wjwwood/serial.git  (开 ...

  10. Python内置函数之staticmethod()

    staticmethod(function)返回函数的静态方法.一般来说,实例对象调用类方法不用传入参数,因为实例对象本身隐式的作为第一个参数传入了.而采用静态方法之后,实例对象在调用类方法时必须传入 ...