三目运算符和if else哪个效率高_面试官:你写的if、else太多啦

当if else结构变得复杂难以维护时,可以尝试提前return、使用三目运算符、Optional、switch case、枚举、表驱动法和策略模式+工厂模式进行优化。这些方法能提高代码可读性和效率,例如,switch通过哈希比较实现O(1)复杂度,而Optional则提供优雅的非空检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在代码编写初期,我们写出来的代码,脉络清晰,结构简单。可随着bug或者新需求的出现,状态变得越来越多,只能不停地加else来区分,久而久之,判断的次数越来越多,嵌套的层数也越来越深,变得难以维护。

eb001d03739a89572aa3d230ea3e57ae.png

当我们狠下心来决定改造时,有哪些方法能够优化if else结构呢?


第一种方法:提前return,减少else判断

优化前:

    private int handlePre1(boolean flag) {        if (flag) {            //do something        } else {            //do something            return -1;        }        return 0;    }

优化后:

    private int handleAfter1(boolean flag) {        if (!flag) {            //do something            return -1;        }        //do something        return 0;    }

这个做法,将可以return的状态提到if中,直接干掉了else!


第二种方法:使用三目运算符

优化前:

    private int handlePre2(boolean flag) {        if (flag) {            return 0;        } else {            return 1;        }    }

优化后:

    private int handleAfter2(boolean flag) {        return flag ? 0 : 1;    }

这种方式局限性比较大,但对于那些依据状态直接返回某个值的情况非常适用,优化后代码非常简洁。如果三目运算符中还嵌套一层三目运算符,建议就不要使用这种方式了。


第三种方法:使用Optional

我们在代码中,经常需要判断某个对象是否为null,不为null后才会进行接下来的操作,好在java8为我们提供了Optional类。

优化前:

        User user = new User();        int age = 20;        if (user != null) {            age = user.getAge();        }

优化后:

        User user = new User();        Optional optionalUser = Optional.ofNullable(user);        Integer age = optionalUser.map(User::getAge).orElse(20);

Optional让非空校验更加有优雅,代码层面减少了if判断,其实Optional在底层为我们封装好了if null判断而已。


第四种方法:使用switch case

优化前:

    private String getCn(String en) {        String cn;        if ("student".equals(en)) {            cn = "学生";        } else if ("teacher".equals(en)) {            cn = "教师";        } else {            cn = "未知";        }        return cn;    }

同样,我们可以借鉴方式一提前return,来代替else

    private String getCnByEarlyReturn(String en) {        if ("student".equals(en)) {            return "学生";        }        if ("teacher".equals(en)) {            return "教师";        }        return "未知";    }

如果这里面的情况很多,我们可能依然要判断多次,那我们用switch改写。

优化后:

    private String getCnBySwitch(String en) {        switch (en) {            case "student":                return "学生";            case "teacher":                return "教师";            default:                return "未知";        }    }

如果单从效率来看,之前的时间复杂度为O(n),switch的复杂度为O(1),本质上swicth是通过比对String的哈希码来实现的。


第五种方法:使用枚举

如果上一例中的student、teacher是常量的话,最好是定义在枚举里。

    public enum CnEnum {        STUDENT("student", "学生"),        TEACHER("teacher", "教师"),        UNKNOWN("unKnown", "未知");        private String en;        private String cn;        public String getEn() {            return en;        }        public String getCn() {            return cn;        }        CnEnum(String en, String cn) {            this.en = en;            this.cn = cn;        }        static String of(String en) {            for (CnEnum temp : CnEnum.values()) {                if (temp.getEn().equals(en)) {                    return temp.getCn();                }            }            return CnEnum.valueOf("UNKNOWN").getCn();        }    }

最后这样调用即可:

        String cn = CnEnum.of("student");

第六种方法:表驱动法

表驱动法是指我们可以将信息存在于表中,从表中取,而不必用if else逻辑去寻找,大可以将这里的“表”理解为一种容器。

例如我们可以将每月的天数存在数组中,需要时,直接从数组中获取,而不是用if else输出。

或者依据不同的字符串,执行不同的处理逻辑。if else版本如下:

        String profession = "student";        if ("student".equals(profession)) {           //do something        } else if ("teacher".equals(profession)) {            //do something        } else if ("programmer".equals(profession)) {            //do something        }

在这种情况下,使用表驱动法后,可以让Student、Teacher等类实现某一个共同的接口,在实现方法里,书写各自的逻辑。然后利用Spring强大的自动注入,会注入到Map的map里,之后直接根据组件名称来获取到对应的实例,最后调用各自的逻辑。

这个例子可以先异步到我的另外一篇文章【SpringBoot】使用不同的策略动态地调用某个接口的实现类


第七种方法:策略模式+工厂模式

首先给定以下的一个场景,传入一个职业,输出职业的主要工作

一般我们会这么写:

        String profession = "student";        if ("student".equals(profession)) {            System.out.println("学习");        } else if ("teacher".equals(profession)) {            System.out.println("教书");        } else if ("programmer".equals(profession)) {            System.out.println("写代码");        }        //.......以后可能会加上各种各样的职业

那么,每增加一种职业,就会增加一个if else判断,代码可读性差,日后难以维护。

现在使用策略模式+工厂模式来改造它。

  • 首先定义一个职业接口,里面定义一个输出职责的方法
  • 之后每增加一种职业,都实现职业接口,实现输出职责的方法(策略模式)
  • 接着定义一个工厂类,用来根据具体情况生产各种职业类(工厂模式)

职业接口:

public interface Profession {    //输出职责    void output();}

实现类:

public class Student implements Profession {    @Override    public void output() {        System.out.println("学习");    }}public class Teacher implements Profession {    @Override    public void output() {        System.out.println("教书");    }}public class Programmer implements Profession {    @Override    public void output() {        System.out.println("写代码");    }}

工厂类:

public class ProfessionFactory {    private static Map map = new HashMap<>();    //未知职业    private static final Profession DEFAULT_PROFESSION = new DefaultProfession();    static {        map.put("student", new Student());        map.put("teacher", new Teacher());        map.put("default", DEFAULT_PROFESSION);    }    public static Profession getProfession(String s) {        Profession profession = map.get(s);        return profession == null ? DEFAULT_PROFESSION : profession;    }    static class DefaultProfession implements Profession {        @Override        public void output() {            System.out.println("职责未知");        }    }}

优化后:

        Profession profession = ProfessionFactory.getProfession("student");        profession.output();

之后每增加一种职业,只要实现Profession接口就好,并在ProfessionFactory中注册自己。使用策略模式+工厂模式,再也不需要为日益增长的if else头疼了。

当然,这里的key值,可以设置为常量。


总结

过多的if else严重降低可读性与可维护性,所以在一开始,就要依据实际情况,灵活地选择处理方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值