A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 曹老师 黑马粉丝团   /  2017-9-11 22:47  /  923 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

(1)java优化的目的:
   a>减少代码量
   b>提高java运行的效率
(2)java常见的优化场景:
        1.开发过程中声明常量,不可继承类,不可重写方法,使用final
          如:private final String hello="wolrd";
        2.String,StringBuffer,StringBuilder
           a>常量字符串拼接选择“String”
                        String s1="hello"+"world"; //选择String
                        StringBuilder sb=new StringBuilder();
                        sb.append("hello");
                        sb.append("world");
           b>一般执行速度StringBuilder>StringBuffer>String
           c>StringBuffer线程安全,StringBuilder是非线程安全
              StringBuilder//在单线程下,操作大量数据可以使用,应该保证了线程安全且执行速度很快
                  StringBuffer//在多线程下,操作大量数据可以使用,保证了线程安全
           d>String是字符串常量,StringBuilder和StringBuffer是字符串变量
              String:private final char value[];
                  StringBuilder/StringBuffer:char[] value;
        3.及时关闭io流,释放资源
           文件操作,数据库操作
        4.减少变量重复计算
           for (int i = 0; i < list.size(); i++) {}//每次循环,就得计算一次list.size()
           建议替换为:
           for (int i = 0, int length = list.size(); i < length; i++) {}
        5.尽量使用懒加载
           String str = "aaa";
                if (i == 1) {
                        list.add(str);
                }
                建议替换为:
                if (i == 1) {
                        String str = "aaa";
                        list.add(str);
                }
        6.不要在循环中使用try…catch…,应该把其放在最外层
           try{
                   for(){}
           }
           catch(){
           }
        7.如果能估计到待添加的内容长度,为底层以数组方式实现的集合、工具类指定初始长度
          比如ArrayList、LinkedLlist、StringBuilder、StringBuffer、HashMap、HashSet等等
             StringBuilder()// 默认分配16个字符的空间
                 StringBuilder(int size)// 默认分配size个字符的空间
                 StringBuilder(String str) // 默认分配16个字符+str.length()个字符空间
          注意:当StringBuilder达到最大容量的时 候,它会将自身容量增加到当前的2倍再加2,
          无论何时只要StringBuilder达到它的最大容量,它就不得不创建一个新的字符数组然后将旧的字符数 组内容拷贝到新字符数组中—-这是十分耗费性能的一个操作
       
        8.乘法和除法使用移位操作
           for (val = 0; val < 100000; val += 5) {
                 a = val * 8;
                 b = val / 2;
                }
                建议改成:
           for (val = 0; val < 100000; val += 5) {
                 a = val << 3;
                 b = val >> 1;
                }
        9.循环内不要不断创建对象引用
           for (int i = 1; i <= count; i++)  {
                        Object obj = new Object();  
       }
           建议为改为:
           Object obj = null;
           for (int i = 0; i <= count; i++) { obj = new Object(); }
        10.线程安全和效率不能同时兼得
                尽量使用HashMap、ArrayList、StringBuilder,
                除非线程安全需要,否则不推荐使用Hashtable、Vector、StringBuffer,
                后三者由于使用同步机制而导致了性能开销
        11.尽量避免随意使用静态变量
           public class A {
                        private static B b = new B();
           }
           注意:当某个对象被定义为static的变量所引用,那么gc通常是不会回收这个对象所占有的堆内存的
        12.实现RandomAccess接口的集合比如ArrayList,应当使用最普通的for循环而不是foreach循环来遍历
           实际经验表明,实现RandomAccess接口的类实例,假如是随机访问的,
           使用普通 for循环效率将高于使用foreach循环;反过来,
           如果是顺序访问的,则使用Iterator会效率更高。可以使用类似如下的代码作判断
        13.将常量声明为static final,并以大写命名
           private static final String NAME="Robin";
        14.不要创建一些不使用的对象,不要导入一些不使用的类
           清除多余无关的类
        15.使用数据库连接池和线程池
          这两个池都是用于重用对象的,前者可以避免频繁地打开和关闭连接,
          后者可以避免频繁地创建和销毁线程
        16.使用带缓冲的输入输出流进行IO操作
          带缓冲的输入输出流,即BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream,
          这可以极大地提升IO效率  
        17.顺序插入和随机访问比较多的场景使用ArrayList,元素删除和中间插入比较多的场景使用LinkedList
         这个,理解ArrayList和LinkedList的原理就知道了
        18.字符串变量和字符串常量equals的时候将字符串常量写在前面
           String str = "123";
           if (str.equals("123")) { }
          建议改成:
           String str = "123";
           if ("123".equals(str)) {}
        19.请知道,在java中if (i == 1)和if (1 == i)是没有区别的,但从阅读习惯上讲,建议使用前者
          int i = 2;
          if (i == 1) {}
          如果将“==”误写成了“=”
          int i = 2;if (i = 1) { ... }else{ ... }
        20.把一个基本数据类型转为字符串,基本数据类型.toString()是最快的方式、String.valueOf(数据)次之、数据+”"最慢
           请不要使用数据+"";
           a>String.valueOf()方法底层调用了Integer.toString()方法,但是会在调用前做空判断
           b>Integer.toString()方法就不说了,直接调用了
           c>i + ""底层使用了StringBuilder实现,先用append方法拼接,再用toString()方法获取字符串
             如:String s=1+"";
        21.使用最有效率的方式去遍历Map<KeySet,EntrySet,values,Iterator>
           map最全的4种遍历方式:
           a>在for-each循环中使用entries来遍历
              Map<Integer, Integer> map = new HashMap<Integer, Integer>();  
                  for (Map.Entry<Integer, Integer> entry : map.entrySet()) {  
                                System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());   
                  }  
           b>在for-each循环中遍历keys或values。
              Map<Integer, Integer> map = new HashMap<Integer, Integer>();  
                  //遍历map中的键  
                  for (Integer key : map.keySet()) {  
                                System.out.println("Key = " + key);  
              }  
                  //遍历map中的值  
                  for (Integer value : map.values()) {  
                        System.out.println("Value = " + value);  
                  }  
            c>通过键找值遍历(效率低)
                  Map<Integer, Integer> map = new HashMap<Integer, Integer>();  
                  for (Integer key : map.keySet()) {  
                        Integer value = map.get(key);  
                        System.out.println("Key = " + key + ", Value = " + value);   
                  }  
            d>最快的方式:
                   HashMap<String, String> hm = new HashMap<String, String>();
                   hm.put("111", "222");
                   Set<Map.Entry<String, String>> entrySet = hm.entrySet();
                   Iterator<Map.Entry<String, String>> iter = entrySet.iterator();
                   while (iter.hasNext()) {
                                Map.Entry<String, String> entry = iter.next();
                                System.out.println(entry.getKey() + "\t" + entry.getValue());
                        }
              如果想要获取key,只需要获得keyset
        22.对资源的close()建议分开操作
            try{
                        XXX.close();
                    YYY.close();
                }catch (Exception e) {
                }
            建议改成:
                try{
                        XXX.close();
                }
                catch (Exception e) {
                }
                try{
                        YYY.close();
                }
                catch (Exception e) {
                }
               

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马