java基础-代码性能优化常见场景

java优化的目的:

   a>减少代码量

   b>提高java运行的效率

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++) {}
       for(;;){} 死循环
       while(true){}

5.尽量使用懒加载      

 String str = "aaa";
        if (i == 1) {
            list.add(str);
        }
        建议替换为:
        if (i == 1) {
            String str = "aaa";
            list.add(str);
        }

6.不要在循环中使用try…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) {
        }finally{
           xxx=null;
        }

        try{
            YYY.close();
        } catch (Exception e) {
        }finally{

           yyy=null;

        }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值