zoukankan      html  css  js  c++  java
  • 从性能角度分析一下String,List,Map

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

      public static void testH() {
        List<String> strings = new ArrayList<String>();
        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<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 = 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<Integer, String> 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<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(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<Integer> 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<Integer> 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);
      }
  • 相关阅读:
    怎么知道银行卡号对应的银行
    集合排序、map、枚举
    669. Trim a Binary Search Tree修剪二叉搜索树
    17. Merge Two Binary Trees 融合二叉树
    226. Invert Binary Tree 翻转二叉树
    530.Minimum Absolute Difference in BST 二叉搜索树中的最小差的绝对值
    191. Number of 1 Bits 二进制中1的个数
    Hamming Distance二进制距离
    136. Single Number唯一的数字
    276. Paint Fence篱笆涂色
  • 原文地址:https://www.cnblogs.com/badboyf/p/6529178.html
Copyright © 2011-2022 走看看