zoukankan      html  css  js  c++  java
  • java 枚举类型使用总结

    注:阅读了effective java 讲诉enum的部分,做下笔记,下文中大部分代码来自effective java书中

    枚举类型是指由一组固定的常量组成的合法值得类型。

    使用枚举的好处:a,因为没有可以访问的构造器,枚举类型是真正的final;

            b,枚举类型提供类编译时的类型安全。如:函数中声明一个参数类型为枚举类型的Apple时,那么调用方法时传递到参数上的任何非null对象一定是Apple的值之一,         而是用静态常量就无法保证;

            c,包含同名常量的多个枚举类型可以和平共处,每个类型都有自己的命名空间

            d,枚举类型允许添加任意的方法和域,并可实现接口。

    1,常见的一组简单的枚举

    如:

    public enum Apple {
        FUJI,PIPPIN,CRANNY_SMITH
    }

    2,带有具体值的枚举(可自定义方法)

    public enum Apple {
        FUJI(1), PIPPIN(2), CRANNY_SMITH(3);
        
        private final int code;
        
        Apple(int code) {
            this.code = code;
        }
    
        public int getCode() {
            return code;
        }
    
        public static Apple fromCode(int code) {
            for (Apple apple : Apple.values()) {
                if (apple.getCode() == code)
                    return apple;
            }
            return null;
        }
    }

    3,多个参数,并带有运算方法

    public enum Planet {
    
        MERCURY(3.303e+23, 2.4397e6),
        VENUS(4.869e+24, 6.0518e6),
        EARTH(5.976e+24, 6.37814e6),
        MARS(6.421e+23, 3.3972e6),
        JUPITER(1.9e+27, 7.1492e7),
        SATURN(5.688e+26, 6.0268e7),
        URANUS(8.686e+25, 2.5559e7),
        NEPTUNE(1.024e+26, 2.4746e7),
        PLUTO(1.27e+22, 1.137e6);
        
        private final double mass;
    
        private final double radius;
    
        private final double surfaceGravity;// m/ s^2
    
        public static final double G = 6.67300E-11;
    
        Planet(double mass, double radius) {
            this.mass = mass;
            this.radius = radius;
            surfaceGravity = G * mass / (radius * radius);
        }
    
        public double mass() {
            return mass;
        }
    
        public double radius() {
            return radius;
        }
    
        public double surfaceWeight(double otherMass) {
            return otherMass * surfaceGravity;
        }
    }

    4,根据不同的常量有不同的方法

      switch方法 ----不推荐(有可能新添加了常量却没有在switch中加入就悲剧了)

    public enum Operation {
        PLUS("+"),
        MINUS("-"),
        TIMES("*"),
        DIVIDE("/");
        
        private final String symbol;
        Operation(String symbol){
            this.symbol=symbol;
        }
        
        public String getSymbol() {
            return symbol;
        }
    
        double apply(double x,double y){
            switch(this){
            case PLUS:return x + y;
            case MINUS:return x - y;
            case TIMES:return x * y;
            case DIVIDE:return x / y;
            }
            throw new AssertionError("unknown operation: "+this);
        }

      推荐:constant-specific method implementation

    public enum Operation {
        PLUS("+") {
            public double apply(double x, double y) {
                return x + y;
            }
        },
        MINUS("-") {
            public double apply(double x, double y) {
                return x - y;
            }
        },
        TIMES("*") {
            public double apply(double x, double y) {
                return x * y;
            }
        },
        DIVIDE("/") {
            public double apply(double x, double y) {
                return x / y;
            }
        };
    
        private final String symbol;
    
        Operation(String symbol) {
            this.symbol = symbol;
        }
    
        public String getSymbol() {
            return symbol;
        }
    
        public abstract double apply(double x, double y);
    
    }

    5,策略枚举 strategy enum

    先来看一种情况:通过一周的工作时间来计算工资,工作时间8小时,额外算加班,周末工作也算加班

    首先我们可以使用switch来做,这样看起来十分简单

    public enum PayrollDay {
        MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FIRDAY, SATURDAY, SUNDAY;
    
        private static final int HOURS_PER_SHIFT = 8;
    
        double pay(double hoursWorked, double payRate) {
            double basePay = hoursWorked * payRate;
            double overtimePay;
            switch (this) {
            case SATURDAY:
            case SUNDAY:
                overtimePay = hoursWorked * payRate * 2;
            default:
                overtimePay = hoursWorked <= HOURS_PER_SHIFT ? 0
                        : (hoursWorked - HOURS_PER_SHIFT) * payRate * 2;
                break;
            }
            return basePay + overtimePay;
        }
    }

    但是同样有可能出现上面提到不严谨的问题,当枚举常量增加时,switch可能忘记加入

    使用策略枚举时 如下:

    public enum PayrollDay {
        MONDAY(PayType.WEEKDAY), TUESDAY(PayType.WEEKDAY), WEDNESDAY(
                PayType.WEEKDAY), THURSDAY(PayType.WEEKDAY), FIRDAY(PayType.WEEKDAY), SATURDAY(
                PayType.WEEKEND), SUNDAY(PayType.WEEKEND);
    
        private final PayType payType;
    
        PayrollDay(PayType payType) {
            this.payType = payType;
        }
    
        public PayType getPayType() {
            return payType;
        }
    
        double pay(double hoursWorked, double payRate) {
            return payType.pay(hoursWorked, payRate);
        }
    
        enum PayType {
            WEEKDAY {
                @Override
                double overtimePay(double hours, double payRate) {
                    return hours < HOURS_PER_SHIFT ? 0 : (hours - HOURS_PER_SHIFT)
                            * payRate * 2;
                }
            },
            WEEKEND {
                @Override
                double overtimePay(double hours, double payRate) {
                    return hours * payRate * 2;
                }
            };
            private static final int HOURS_PER_SHIFT = 8;
    
            abstract double overtimePay(double hours, double payRate);
    
            double pay(double hoursWorked, double payRate) {
                double basePay = hoursWorked * payRate;
                return basePay + overtimePay(hoursWorked, payRate);
            }
        }
    }

    6,上面几个例子中都不推荐时间switch,那么什么时候使用呢

    枚举中的switch语句适用于给外部的枚举类型增加特定于常量的行为。如:上面例子中的operation 如果希望他有一个方法返回对应的逆运算

    public static Operation inverse(Operation op) {
            switch (op) {
            case PLUS:
                return Operation.MINUS;
            case MINUS:
                return Operation.PLUS;
            case TIMES:
                return Operation.DIVIDE;
            case DIVIDE:
                return Operation.TIMES;
            default:
                throw new AssertionError("unknown operation : " + op);
            }
        }
  • 相关阅读:
    C#线程的IsBackgroud属性动态设置
    asp.net 异步
    IBM一些Java文章
    (一)Apollo配置中心介绍
    样式表中的 element.style样式如何修改
    jquery中的append和js原生中的innerhtml的区别
    如何在datagrid中的column获取json数据
    快速排序
    冒泡排序
    二进制中有多少个1?
  • 原文地址:https://www.cnblogs.com/china2k/p/4067539.html
Copyright © 2011-2022 走看看