博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从性能角度分析一下String,List,Map
阅读量:4552 次
发布时间:2019-06-08

本文共 5228 字,大约阅读时间需要 17 分钟。

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

public static void testH() {    List
strings = new ArrayList
(); for (int i = 0; i < 1000; i++) { HugeStr h = new HugeStr(); // ImprovedHugeStr h = new ImprovedHugeStr(); strings.add(h.getSubString(1, 5)); } } static class HugeStr { private String str = new String(new char[10000]); String getSubString(int begin, int end) { return str.substring(begin, end);        //会内存溢出 } } static class ImprovedHugeStr { private String str = new String(new char[10000]); 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 = 0; i < 1000; i++) {      sb.append(i);      sb.append(":");    }    return sb.toString();  }  static void normalSplidTest() {    String orgStr = initOrgStr();    for (int i = 0; i < 10000; i++) {      orgStr.split(";");    }  }  static void stringTokenizerTest() {    String orgStr = initOrgStr();    StringTokenizer st = new StringTokenizer(orgStr, ":");    for (int i = 0; i < 10000; i++) {      while (st.hasMoreElements()) {        st.nextElement();      }      st = new StringTokenizer(orgStr, ":");    }  }  static void selfSplidTest() {    String orgStr = initOrgStr();    String tmp = orgStr;    for (int i = 0; i < 10000; i++) {      while (true) {        String splitStr = null;        int j = tmp.indexOf(":");        if (j < 0) {          break;        }        splitStr = tmp.substring(0, j);        tmp = tmp.substring(j + 1);      }      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 = 0; i < 10000; i++) {      s += i;    }    String result = "";    for (int i = 0; i < 10000; i++) {      result = result.concat(String.valueOf(i));    }    StringBuilder sb = new StringBuilder();    for (int i = 0; i < 10000; 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
list) { String tmp; for (String s : list) { tmp = s; } for (Iterator
it = list.iterator(); it.hasNext();) { tmp = it.next(); } int size = list.size(); for (int i = 0; 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
map = new LinkedHashMap<>(16, 0.75F, false); map.put(3, "k"); map.put(1, "f"); map.put(2, "z"); map.put(7, "z"); map.put(8, "z"); map.put(6, "z"); map.put(4, "z"); map.put(5, "z"); map.get(8); map.get(7); map.get(6); for (Iterator
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
map = new TreeMap<>(); map.put(3, "k"); map.put(1, "f"); map.put(2, "z"); map.put(7, "z"); map.put(8, "z"); map.put(6, "z"); map.put(4, "z"); map.put(5, "z"); for (Iterator
iterator = map.keySet().iterator(); iterator.hasNext();) { Integer key = (Integer) iterator.next(); System.out.println(key); } Map map2 = ((TreeMap) map).subMap(1, 4); System.out.println("get the key more than or equal 1 and less than 4"); for (Iterator
iterator = map2.keySet().iterator(); iterator.hasNext();) { Integer key = (Integer) iterator.next(); System.out.println(key); } // 小于2的 Map map3 = ((TreeMap) map).headMap(2); // 大于2的 Map map4 = ((TreeMap) map).tailMap(2); }

 

转载于:https://www.cnblogs.com/badboyf/p/6529178.html

你可能感兴趣的文章
CSS定位深入理解 完全掌握CSS定位 相对定位和绝对定位
查看>>
网络体系结构
查看>>
练习4.13、4.14、4.15、4.16
查看>>
SAP库龄表
查看>>
PhantomJS 基础及示例 (转)
查看>>
20175316盛茂淞 2018-2019-2 《Java程序设计》第3周学习总结
查看>>
zookeeper安装
查看>>
js清空页面控件值
查看>>
Appium使用Python运行appium测试的实例
查看>>
django request bug
查看>>
二叉树_非递归先中后序_递归非递归求深度
查看>>
20181227 新的目标
查看>>
HDFS写流程
查看>>
生产环境服务器环境搭建+ 项目发布
查看>>
js按条件分类json数组,并合计同组数据(一维转换为二维)
查看>>
Exp6 信息搜集与漏洞扫描
查看>>
redis4安装
查看>>
随机生成双色球号码
查看>>
使用命令wsimport构建WebService客户端[转]
查看>>
第八遍:链接详解
查看>>