使用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. 51单片机 | 定时/计数器原理及结构(T0和T1)

    ———————————————————————————————————————————— 定时/计数器结构(T0和T1) 16位寄存器T0.T1分别由TH0.TL0和TH1.TL1四个8位计数器组成 ...

  2. spring aop中的propagation(传播属性)的7种配置的意思

      1.前言. 在声明式的事务处理中,要配置一个切面,即一组方法,如 <tx:advice id="txAdvice" transaction-manager="t ...

  3. struct和class的不同以及struct的应用场景

    struct在C#中被用来定义结构,它是一种比类小的数据类型.和类一样都是创建对象的模板,可以有自己的数据以及处理和访问数据的方法. struct的用法: struct FurnitureSize { ...

  4. 2.JAVA编程思想——一切都是对象

    一切都是对象 欢迎转载.转载请标明出处:http://blog.csdn.net/notbaron/article/details/51040221 虽然以C++为基础,但 Java 是一种更纯粹的面 ...

  5. 远程桌面工具 TeamViewer

    在家里想远程公司的电脑 教程: http://jingyan.baidu.com/article/d169e186b38c37436611d8fa.html 下载地址: http://rj.baidu ...

  6. Spring Boot(六): Favicon配置

    1.默认的Favicon Spring Boot提供了一个默认的Favicon,每次访问应用的时候都能看到,如图所示. 2.关闭Favicon 我们可以在application.properties中 ...

  7. MQTT服务器搭建--Apollo

    尊重原创,我是伸手党:https://blog.csdn.net/u012377333/article/details/68943416 1.Apollo下载 下载地址:http://activemq ...

  8. 使用mescroll实现上拉加载与下拉刷新

    现在上拉加载与下拉刷新几乎已经是移动端必备功能之一了,自己实现一个太麻烦,但是好用的插件又非常少.之前看到网上很多人都在用iScroll,于是也尝试用它做了几个DEMO,但或多或少都有一些问题,比如这 ...

  9. android:分享 一个非常强大的LOG开关---Log.isLoggable

    1.API亮点: 此API能够实现不更换APK.在出问题的手机上就直接能抓到有效log,能提升不少工作效率. .API介绍 近期在解决短信问题时.看到一个非常强大的LOG开关---Log.isLogg ...

  10. vmware workstation(mac版)查看vmnet8的网关地址

    想为虚拟机配置固定ip,需要设置网关,但是mac版的vmware workstation没有Virtual Network Editor,所以不能直接查看到. 因此执行如下命令进行查找 find / ...