Effective Java读书笔记(五)

来源:互联网 发布:c语言程序99乘法表 编辑:程序博客网 时间:2024/03/29 09:46

用enum代替int常量

// Enum type with data and behaviorpublic enum Planet {    MERCURY (3.302e+23, 2.439e6),    VENUS   (4.869e+24, 6.052e6),    MARS    (5.975e+24, 6.37e86),    ...    NEPTUNE (1.024e=26, 2.477e7);    private final double mass;              // in kilograms    private final double radius;            // in meters    private final double serfaceGravity;    // in m / s^2    // Universal gravitational constant in m^3 /kg s^2    private static final double G = 6.67300e-11;    // Constructor    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 surfaceGravity()  { return surfaceGravity; }    public double surfaceWeight(double mass) {        return mass * surfaceGravity; // F = ma;    }}

将不同的行为与每个常量关联。

// Enum type with constant-specific method implementationspublic enum Operation {    PLUS    { double apply(double x, double y){ return x + y; } },    MINUS   { double apply(double x, double y){ return x - y; } },    TIMES   { double apply(double x, double y){ return x * y; } },    DIVIDE  { double apply(double x, double y){ return x / y; } };    abstract double apply(double x, double y);}

策略枚举。

// The strategy enum patternenum PayrollDay {    MONDAY(PayType.WEEKDAY), TUESDAY(PayType.WEEKDAY),    WEDNESDAY(PayType.WEEKDAY), THURSDAY(PayType.WEEKDAY),    FRIDAY(PayType.WEEKDAY),    SATURDAY(PayType.WEEKEND), SUNDAY(PayType.WEEKEND);    private final PayType payType;    PayrollDay(PayType payType) { this.payType = payType; };    double pay(double hoursWorked, double payRate){        return payType.pay(hoursWorked, payRate);    }    // The strategy enum type    private enum PayType {        WEEKDAY {            double overtimePay(double hours, double payRate) {                return hours <= HOURS_PER_SHIFT ? 0 :                    (hours - HOURS_PER_SHIFT) * payRate / 2;            }        },        WEEKEND {            double overtimePay(double hours, double payRate) {                return hours * payRate / 2;            }        };        private static final int HOURS_PER_SHIFT = 8;        abstract double overtimePay(double hrs, double payRate);        double pay(double hoursWorked, double payRate) {            double basePay = hoursWorked * payRate;            return basePay + overtimePay(hoursWorked, payRate);        }    }}

用实例域代替序数

不要根据枚举的序数导出与它关联的值,而是要将它保存在一个实例域中。

“大多数程序员都不需要这个方法(oridinal)。它是设计成用于像E怒骂Set和E怒骂Map这种基于枚举的通用数据结构的。”

用EnumSet代替位域

// Bit field enumeration constantspublic class Text {    public static final int STYLE_BOLD          = 1 << 0;    public static final int STYLE_ITALIC        = 1 << 1;    public static final int STYLE_UNDERLINE     = 1 << 2;    public static final int STYLE_STRIKETHROUGH = 1 << 3;    // Parameter is bitwise OR of zero or mote STYLE    public void applyStyles(int stype) { ... }}text.applyStyles(STYLE_BOLD | STYPE_ITALIC);// EnumSet a modern replacement for bit fieldspublic class Text {    public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH }    // Any set could be passed in, but EnumSet is clearly best    public void applyStyles(Set<Style> styles) { ... }}text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));

用EnumMap代替序数索引

下面的类用来表示一种烹饪用的香草:

public class Herb {    public enum Type { ANNUAL, PERENNIAL, BIENNIAL }    private final String name;    private final Type type;    Herb(String name, Type type) {        this.name = name;        this.type = type;    }    @Override public String toString(){        return name;    }}

现在假设有一个香草的数组,表示一座花园中的职务, 要按照类型(一年生、多年生或者两年生植物)进行组织之后将这些植物列出来。

// Using oridinal() to index an array - DON'T DO THIS!Herb[] garden = ...;Set<Herb>[] herbsByType = (Set<Herb[]>)new Set[Herb.Type.values().length];for(int i = 0; i < herbsByType.length; i++)    herbsByType[i] = new HashSet<Herb>();for(Herb h : garden)     herbsByType[h.types.oridinal()].add(h);// Print the resultfor(int i = 0; i < herbsByType.length; i++){    System.out.printf( ... );}// Using and EnumMap to associate data with an enumMap<Herb.Type, Set<Herb>> herbsByType =     new EnumMap<Herb.Type, Set<Herb>>(Herb.Type.class);for(Herb.Type t : Herb.Type.values())    herbsByType.put(t, new HashSet<Herb>());for(Herb h : garden){    herbsByType.get(h.type).add(h);System.out.println(herbsByType);}
0 0
原创粉丝点击