看完这些 Java 代码优秀案例,一定对你有提升

告别『面向屎山编程』!这份『人类友好』设计模式指南,让你代码优雅永流传 接手一个老项目,代码逻辑盘根错节,改一个Bug引出十个新Bug,每一次改动都像是如履薄冰。自己的项目越写越臃肿,新功能迭代困难,扩展性差,最后连自己都不想维护了。团队协作时,同事写的代码让你抓狂,可读性极差,难以理解。面试时被问到『设计模式』,却支支吾吾,只能背几个概念,无法深入浅出地讲解,更别提实际应用了。如果你有以上任何一种困扰,那么恭喜你,你不是一个人在战斗!这正是软件开发中最常见的“代码质量”痛点。 阅读详情

前言

程序的性能受到代码质量的直接影响。这次主要介绍一些代码编写的小技巧和惯例。虽然看起来有些是微不足道的编程技巧,却可能为系统性能带来成倍的提升,因此还是值得关注的。

慎用异常

在Java开发中,经常使用try-catch进行错误捕获,但是try-catch语句对系统性能而言是非常糟糕的。虽然一次try-catch中,无法察觉到它对性能带来的损失,但是一旦try-catch语句被应用于循环或是遍历体内,就会给系统性能带来极大的伤害。

以下是一段将try-catch应用于循环体内的示例代码:

@Test
    public void test11() {

        long start = System.currentTimeMillis();
        int a = 0;
        for(int i=0;i<1000000000;i++){
            try {
                a++;
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        long useTime = System.currentTimeMillis()-start;
        System.out.println("useTime:"+useTime);
    }	

上面这段代码运行结果是:

useTime:10

下面是一段将try-catch移到循环体外的代码,那么性能就提升了将近一半。如下:

@Test
    public void test(){
        long start = System.currentTimeMillis();
        int a = 0;
        try {
            for (int i=0;i<1000000000;i++){
                a++;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        long useTime = System.currentTimeMillis()-start;
        System.out.println(useTime);
    }

运行结果:

useTime:6

使用局部变量

调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度快。其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢。

下面是一段使用局部变量进行计算的代码:

@Test
    public void test11() {

        long start = System.currentTimeMillis();
        int a = 0;
        for(int i=0;i<1000000000;i++){
            a++;
        }
        long useTime = System.currentTimeMillis()-start;
        System.out.println("useTime:"+useTime);

    }

运行结果:

useTime:5

将局部变量替换为类的静态变量:

static int aa = 0;
    @Test
    public void test(){
        long start = System.currentTimeMillis();

      for (int i=0;i<1000000000;i++){
            aa++;
        }
        long useTime = System.currentTimeMillis()-start;
        System.out.println("useTime:"+useTime);
    }

运行结果:

useTime:94

通过上面两次的运行结果,可以看出来局部变量的访问速度远远高于类成员变量。

位运算代替乘除法

在所有的运算中,位运算是最为高效的。因此,可以尝试使用位运算代替部分算术运算,来提高系统的运行速度。最典型的就是对于整数的乘除运算优化。

下面是一段使用算术运算的代码:

@Test
    public void test11() {

        long start = System.currentTimeMillis();
        int a = 0;
        for(int i=0;i<1000000000;i++){
            a*=2;
            a/=2;
        }
        long useTime = System.currentTimeMillis()-start;
        System.out.println("useTime:"+useTime);
    }

运行结果:

useTime:1451

将循环体中的乘除运算改为等价的位运算,代码如下:

@Test
    public void test(){
        long start = System.currentTimeMillis();
        int aa = 0;
        for (int i=0;i<1000000000;i++){
            aa<<=1;
            aa>>=1;
        }
        long useTime = System.currentTimeMillis()-start;
        System.out.println("useTime:"+useTime);
    }

运行结果:

useTime:10

上两段代码执行了完全相同的功能,在每次循环中,都将整数乘以2,并除以2。但是运行结果耗时相差非常大,所以位运算的效率还是显而易见的。

提取表达式

在软件开发过程中,程序员很容易有意无意地让代码做一些“重复劳动”,在大部分情况下,由于计算机的高速运行,这些“重复劳动”并不会对性能构成太大的威胁,但若希望将系统性能发挥到极致,提取这些“重复劳动”相当有意义。

比如以下代码中进行了两次算术计算:

@Test
    public void testExpression(){
        long start = System.currentTimeMillis();
        double d = Math.random();
        double a = Math.random();
        double b = Math.random();
        double e = Math.random();

        double x,y;
        for(int i=0;i<10000000;i++){
            x = d*a*b/3*4*a;
            y = e*a*b/3*4*a;
        }
        long useTime = System.currentTimeMillis()-start;
        System.out.println("useTime:"+useTime);

    }

运行结果:

useTime:21

仔细看能发现,两个计算表达式的后半部分完全相同,这也意味着在每次循环中,相同部分的表达式被重新计算了。

那么改进一下后就变成了下面的样子:

@Test
    public void testExpression99(){
        long start = System.currentTimeMillis();
        double d = Math.random();
        double a = Math.random();
        double b = Math.random();
        double e = Math.random();

        double p,x,y;
        for(int i=0;i<10000000;i++){
            p = a*b/3*4*a;
            x = d*p;
            y = e*p;
        }
        long useTime = System.currentTimeMillis()-start;
        System.out.println("useTime:"+useTime);
    }

运行结果:

useTime:11

通过运行结果我们可以看出来具体的优化效果。

同理,如果在某循环中需要执行一个耗时操作,而在循环体内,其执行结果总是唯一的,也应该提取到循环体外。

例如下面的代码:

for(int i=0;i<100000;i++){
    x[i] = Math.PI*Math.sin(y)*i;
}

应该改进成下面的代码:

//提取复杂,固定结果的业务逻辑处理到循环体外
double p = Math.PI*Math.sin(y);
for(int i=0;i<100000;i++){
    x[i] = p*i;
}

使用arrayCopy()

数组复制是一项使用频率很高的功能,JDK中提供了一个高效的API来实现它。

/**
     * @param      src      the source array.
     * @param      srcPos   starting position in the source array.
     * @param      dest     the destination array.
     * @param      destPos  starting position in the destination data.
     * @param      length   the number of array elements to be copied.
     * @exception  IndexOutOfBoundsException  if copying would cause
     *               access of data outside array bounds.
     * @exception  ArrayStoreException  if an element in the <code>src</code>
     *               array could not be stored into the <code>dest</code> array
     *               because of a type mismatch.
     * @exception  NullPointerException if either <code>src</code> or
     *               <code>dest</code> is <code>null</code>.
     */
    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length)

如果在应用程序中需要进行数组复制,应该使用这个函数,而不是自己实现。

下面来举例:

@Test
    public void testArrayCopy(){
        int size = 100000;
        int[] array = new int[size];
        int[] arraydest = new int[size];

        for(int i=0;i<array.length;i++){
            array[i] = i;
        }
        long start = System.currentTimeMillis();
        for (int k=0;k<1000;k++){
            //进行复制
            System.arraycopy(array,0,arraydest,0,size);
        }
        long useTime = System.currentTimeMillis()-start;
        System.out.println("useTime:"+useTime);
    }

运行结果:

useTime:59

相对应地,如果在程序中,自己实现数组复制,其等价代码如下:

@Test
    public void testArrayCopy99(){
        int size = 100000;
        int[] array = new int[size];
        int[] arraydest = new int[size];

        for(int i=0;i<array.length;i++){
            array[i] = i;
        }
        long start = System.currentTimeMillis();
        for (int k=0;k<1000;k++){
            for(int i=0;i<size;i++){
                arraydest[i] = array[i];
            }
        }
        long useTime = System.currentTimeMillis()-start;
        System.out.println("useTime:"+useTime);
    }

运行结果:

useTime:102

通过运行结果可以看出效果。

因为System.arraycopy()函数是native函数,通常native函数的性能要优于普通函数。仅出于性能考虑,在程序开发时,应尽可能调用native函数。

使用Buffer进行I/O操作

除NIO外,使用Java进行I/O操作有两种基本方式;

  • 使用基于InpuStream和OutputStream的方式;
  • 使用Writer和Reader;

无论使用哪种方式进行文件I/O,如果能合理地使用缓冲,就能有效地提高I/O的性能。

InputStream、OutputStream、Writer和Reader配套使用的缓冲组件。

如下图:

使用缓冲组件对文件I/O进行包装,可以有效提升文件I/O的性能。

下面是一个直接使用InputStream和OutputStream进行文件读写的代码:

@Test
    public void testOutAndInputStream(){

        try {
            DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt"));
            long start = System.currentTimeMillis();
            for(int i=0;i<10000;i++){
                dataOutputStream.writeBytes(Objects.toString(i)+"\r\n");
            }
            dataOutputStream.close();
            long useTime = System.currentTimeMillis()-start;
            System.out.println("写入数据--useTime:"+useTime);
            //开始读取数据
            long startInput = System.currentTimeMillis();
            DataInputStream dataInputStream = new DataInputStream(new FileInputStream("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt"));

            while (dataInputStream.readLine() != null){
            }
            dataInputStream.close();
            long useTimeInput = System.currentTimeMillis()-startInput;
            System.out.println("读取数据--useTimeInput:"+useTimeInput);
        }catch (Exception e){
            e.printStackTrace();
        }

    }

运行结果:

写入数据--useTime:660
读取数据--useTimeInput:274

使用缓冲的代码如下:

@Test
    public void testBufferedStream(){

        try {
            DataOutputStream dataOutputStream = new DataOutputStream(
                    new BufferedOutputStream(new FileOutputStream("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt")));
            long start = System.currentTimeMillis();
            for(int i=0;i<10000;i++){
                dataOutputStream.writeBytes(Objects.toString(i)+"\r\n");
            }
            dataOutputStream.close();
            long useTime = System.currentTimeMillis()-start;
            System.out.println("写入数据--useTime:"+useTime);
            //开始读取数据
            long startInput = System.currentTimeMillis();
            DataInputStream dataInputStream = new DataInputStream(
                    new BufferedInputStream(new FileInputStream("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt")));

            while (dataInputStream.readLine() != null){
            }
            dataInputStream.close();
            long useTimeInput = System.currentTimeMillis()-startInput;
            System.out.println("读取数据--useTimeInput:"+useTimeInput);
        }catch (Exception e){
            e.printStackTrace();
        }

    }	

运行结果:

写入数据--useTime:22
读取数据--useTimeInput:12

通过运行结果,我们能很明显的看出来使用缓冲的代码,无论在读取还是写入文件上,性能都有了数量级的提升。

使用Wirter和Reader也有类似的效果。

如下代码:

@Test
    public void testWriterAndReader(){

        try {
            long start = System.currentTimeMillis();
            FileWriter fileWriter = new FileWriter("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt");
            for (int i=0;i<100000;i++){
                fileWriter.write(Objects.toString(i)+"\r\n");
            }
            fileWriter.close();
            long useTime = System.currentTimeMillis()-start;
            System.out.println("写入数据--useTime:"+useTime);
            //开始读取数据
            long startReader = System.currentTimeMillis();
            FileReader fileReader = new FileReader("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt");
            while (fileReader.read() != -1){
            }
            fileReader.close();
            long useTimeInput = System.currentTimeMillis()-startReader;
            System.out.println("读取数据--useTimeInput:"+useTimeInput);
        }catch (Exception e){
            e.printStackTrace();
        }

    }

运行结果:

写入数据--useTime:221
读取数据--useTimeInput:147

对应的使用缓冲的代码:

@Test
    public void testBufferedWriterAndReader(){

        try {
            long start = System.currentTimeMillis();
            BufferedWriter fileWriter = new BufferedWriter(
                    new FileWriter("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt"));
            for (int i=0;i<100000;i++){
                fileWriter.write(Objects.toString(i)+"\r\n");
            }
            fileWriter.close();
            long useTime = System.currentTimeMillis()-start;
            System.out.println("写入数据--useTime:"+useTime);
            //开始读取数据
            long startReader = System.currentTimeMillis();
            BufferedReader fileReader = new BufferedReader(
                    new FileReader("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt"));
            while (fileReader.read() != -1){
            }
            fileReader.close();
            long useTimeInput = System.currentTimeMillis()-startReader;
            System.out.println("读取数据--useTimeInput:"+useTimeInput);
        }catch (Exception e){
            e.printStackTrace();
        }

    }

运行结果:

写入数据--useTime:157
读取数据--useTimeInput:59

通过运行结果可以看出,使用了缓冲后,无论是FileReader还是FileWriter的性能都有较为明显的提升。

在上面的例子中,由于FileReader和FilerWriter的性能要优于直接使用FileInputStream和FileOutputStream所以循环次数增加了10倍。

 

164个java经典代码案例 经典的java代码例子,希望对你有帮助。 立即下载

相关推荐

AD9176 双通道高速DAC调试记录

AD9176是一款高性能双通道16位数模转换器,支持高达12.6GSPS采样率,专为多频段无线应用设计。该器件集成8通道15.4Gbps JESD204B接口,支持复数/实数数据输入,每通道最大输入速率达3.08GSPS。关键特性包括:48位高精度NCO、灵活的插值滤波器(最高12倍)、优异的动态性能(SFDR达-83dBc@1.84GHz)以及多芯片同步功能。硬件调试需重点关注时钟配置(建议250M基准时钟)、JESD参数匹配及交流耦合设计。测试指标要求SFDR>55dBc@312MHz,实测值可达65d

universaldata的博客 1493

50个常用的Java代码示例

java常用的代码例程

秃头男神小伦伦的博客 1万+

SAP FI实战入门:从借贷法则到F-02记账,新手必懂的会计凭证操作

本文详细介绍了SAP FI模块中借贷记账法的核心逻辑及F-02凭证录入的全流程操作。通过实例解析借贷方向规则、科目编码设置及金额镜像原则,帮助新手快速掌握会计凭证操作技巧。同时提供了FS10N余额查询和常见错误排查方法,助力用户高效完成SAP财务记账任务。

weixin_29306571的博客 263

java基础编程案例

Java基础案例

asnowdream的博客 7247

从格雷码到多频外差:结构光相位展开实战指南(附Python仿真代码)

本文深入探讨了结构光三维测量中的相位展开技术,重点对比了格雷码和多频外差法在工业检测、逆向工程等领域的应用。通过详细的原理图解和Python仿真代码,展示了两种方法在精度、抗噪性和适用场景上的差异,为实际工程中的技术选型提供实用指南。

weixin_42535703的博客 435

台达PLC DIAdesigner-AX 编程笔记

1、登陆台达思图软件网站,选择Download,登陆注册好的账号,下载DIAInstaller,下载后安装(安装目录不要修改);

weixin_45823621的博客 6679

看完这些 Java 代码优秀案例,一定对你有提升!

点击上方 "程序员小乐"关注,星标或置顶一起成长每天凌晨00点00分,第一时间与你相约每日英文This is the way I am. I treat well t...

程序员小乐 4858

maxwell与steady state thermal 通过workbench耦合仿真

文章目录maxwellsteady state thermal maxwell 1加入maxwell并打开 2导入模型 3选择求解器类型:涡流求解器eddy current 4修改模型名字不能带_等特殊符号 5为模型赋材料 6设立3D边界,各边电流进出方向为0其余方向300 7设置激励条件,可设置电流大小,相位,方向 8设置集肤深度,选取中间铜导体的体然后设置,如何设置看帮助文档 9求解设置 迭代步数 收敛精度 交流电频率 10验证条件满足计算 11求解 发现无法求解,删除ai

roymustang的博客 9202

看完这些 Java 代码优秀案例,一定对你有提升,华为java面试流程

看完美团、字节、腾讯这三家的面试问题,是不是感觉问的特别多,可能咱们又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。开篇有提及我可是足足背下了1000道题目,多少还是有点用的呢,我看了下,上面这些问题大部分都能从我背的题里找到的,所以今天给大家分享一下互联网工程师必备的面试1000题。注意不论是我说的互联网面试1000题,还是后面提及的算法与数据结构、设计模式以及更多的Java学习笔记等,皆可分享给各位朋友互联网工程师必备的面试1000题而且从上面三家来看,算法与数据结构是必备不可少的。

2401_84002730的博客 771

CMN-700组件全解析:从XP路由器到HN-F主节点的实战配置指南

本文深入解析Arm CMN-700片上网络IP的核心组件与实战配置。重点剖析了XP网格路由器的拓扑规划与CHI通道管理,以及HN-F全一致性主节点在维护缓存一致性、管理SLC和地址映射中的关键作用。通过一个12×12网格的配置案例,为硬件工程师提供了从组件布局、地址映射到性能调优的系统级设计指南。

weixin_29313423的博客 285

Cocos Creator3.5.2使用Spine切换皮肤

3、然后获取当前spine中是否有皮肤数据,如果spine连皮肤数据都没有,接着写可能会error,这里的 skins[skin],是判断皮肤列表中是否有需要更换的皮肤。2、因为spine往往意味着异步加载,换肤时也经常出现频繁异步的情况,所以下一步我们要可以判断当前spine组件里是否已经加载好了spine文件。换肤前隐藏好需要换肤的节点,避免穿帮;官网文档的换肤流程太简化,对于实际使用来说会有各种各样的问题。1、首先获取对应的spine组件。这里的skin自然是外部传入的需要换肤的皮肤名。

tc654321的博客 1820

看完这些 Java 代码优秀案例,一定会对你有提升

前言 程序的性能受到代码质量的直接影响。这次主要介绍一些代码编写的小技巧和惯例。虽然看起来有些是微不足道的编程技巧,却可能为系统性能带来成倍的提升,因此还是值得关注的。 慎用异常 在Java开发中,经常使用try-catch进行错误捕获,但是try-catch语句对系统性能而言是非常糟糕的。虽然一次try-catch中,无法察觉到它对性能带来的损失,但是一旦try-catch语句被应用于循环或是遍历体内,就会给系统性能带来极大的伤害。 以下是一段将try-catch应用于循环体内的示例代码: @

qq_64513388的博客 755

TC3XX - MCAL知识点(三十八):AURIX™ TC3xx 的EDSADC实现旋变解码功能(理论知识+手册阅读)

本文系统梳理了英飞凌AURIX系列芯片EDSADC模块的技术手册内容。首先概述了该模块的架构特点,包括模拟/数字输入通道和总线地址信息。重点解析了手册中的关键知识点:1)模拟量输入的差分/单端模式;2)数字量连接的触发、数据源和时钟源选择;3)功能配置中的寄存器操作注意事项;4)输入通道的三种数据来源模式;5)滤波器链的组成和工作原理;6)旋变应用中的载波信号生成和延迟补偿机制。最后对SRM、SAUL、SBLL等专业术语进行了详细解释。全文为理解EDSADC模块的硬件特性和配置方法提供了系统的技术参考。

梦想技术家 595

看完这些 Java 代码优秀案例,一定对你有提升,值得关注

程序的性能受到代码质量的直接影响。 主要介绍一些代码编写的小技巧和惯例。 虽然看起来有些是微不足道的编程技巧,却可能为系统性能带来成倍的提升,而且也能提高自己的基础知识,扎实的基础是成功的基石,因此还是非常值得关注的。 慎用异常 在Java开发中,经常使用try-catch进行错误捕获,但是try-catch语句对系统性能而言是非常糟糕的。虽然一次try-catch中,无法察觉到她对性能带...

lidamiao 426

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

看完这些 Java 代码优秀案例,一定对你有提升!看完记得抓紧时间收藏!

前言 程序的性能受到代码质量的直接影响。这次主要介绍一些代码编写的小技巧和惯例。虽然看起来有些是微不足道的编程技巧,却可能为系统性能带来成倍的提升,因此还是值得关注的。 慎用异常 在Java开发中,经常使用try-catch进行错误捕获,但是try-catch语句对系统性能而言是非常糟糕的。虽然一次try-catch中,无法察觉到她对性能带来的损失,但是一旦try-catch语句被应用于循环或是遍历体内,就会给系统性能带来极大的伤害。 以下是一段将try-catch应用于循环体内的示例代码: @Test

weixin_46898270的博客 431

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

看完本文的Java 代码优秀案例,一定对你编码水平有所提升

程序的性能受到代码质量的直接影响。这次主要介绍一些代码编写的小技巧和惯例。虽然看起来有些是微不足道的编程技巧,却可能为系统性能带来成倍的提升,因此还是值得关注的。

程序源日志的博客 325

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

资深Java开发工程师优秀代码案例学习探究分享

      哎呀,好久没有更新文章了,年后忙着学习、面试和跳槽,一直也没有进行更新文章,这周刚入职新公司,熟悉了一周项目代码,真是佩服资深Java开发工程师所写的代码啊,正好从明天开始是清明小长假,那我就趁着小长假来分享下优秀代码。为了不让自己懒惰,所以今天我就赶紧先写了个文章开头好让我接下来的几天里能够去付出实际行动。好了,废话少说,祝大家清明节快乐,俺下班喽,接下来几天俺要好好分享俺的代码案例哦;下班了下班了,溜了溜了,拜拜~~~ ...

weixin_45150104的博客 468

Java 代码优秀案例

前言 程序的性能受到代码质量的直接影响。这次主要介绍一些代码编写的小技巧和惯例。虽然看起来有些是微不足道的编程技巧,却可能为系统性能带来成倍的提升,因此还是值得关注的。 慎用异常 在Java开发中,经常使用try-catch进行错误捕获,但是try-catch语句对系统性能而言是非常糟糕的。虽然一次try-catch中,无法察觉到它对性能带来的损失,但是一旦try-catch语句被应用于循环或是遍历体内,就会给系统性能带来极大的伤害。 以下是一段将try-catch应用于循环体内的示例代码: @

wangxi06的专栏 626
上一篇: 不吹不黑,逛GitHub没看过这10个开源项目,绝对血亏
下一篇: 如何破坏单例?我说了好几种方式,面试官:你真会?
JavaShark
博客等级 码龄4年 184粉丝 438原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值