• Effective Java2读书笔记-类和接口(二)


    第15条:使可变性最小化

      通过一个复数类来看不可变类。

    public final class Complex {
        private final double re;
        private final double im;
    
        private Complex(double re, double im) {
            this.re = re;
            this.im = im;
        }
    
        public static Complex valueOf(double re, double im) {
            return new Complex(re, im);
        }
    
        public static Complex valueOfPolar(double r, double theta) {
            return new Complex(r * Math.cos(theta), r * Math.sin(theta));
        }
    
        public static final Complex ZERO = new Complex(0, 0);
        public static final Complex ONE = new Complex(1, 0);
        public static final Complex I = new Complex(0, 1);
    
        public double realPart() {
            return re;
        }
    
        public double imaginaryPart() {
            return im;
        }
    
        public Complex add(Complex c) {
            return new Complex(re + c.re, im + c.im);
        }
    
        public Complex subtract(Complex c) {
            return new Complex(re - c.re, im - c.im);
        }
    
        public Complex multiply(Complex c) {
            return new Complex(re * c.re - im * c.im, re * c.im + im * c.re);
        }
    
        public Complex divide(Complex c) {
            double tmp = c.re * c.re + c.im * c.im;
            return new Complex((re * c.re + im * c.im) / tmp, (im * c.re - re
                    * c.im)
                    / tmp);
        }
    
        @Override
        public boolean equals(Object o) {
            if (o == this)
                return true;
            if (!(o instanceof Complex))
                return false;
            Complex c = (Complex) o;
    
            return Double.compare(re, c.re) == 0 && Double.compare(im, c.im) == 0;
        }
    
        @Override
        public int hashCode() {
            int result = 17 + hashDouble(re);
            result = 31 * result + hashDouble(im);
            return result;
        }
    
        private int hashDouble(double val) {
            long longBits = Double.doubleToLongBits(re);
            return (int) (longBits ^ (longBits >>> 32));
        }
    
        @Override
        public String toString() {
            return "(" + re + " + " + im + "i)";
        }
    }
    View Code

      复数类具有实部和虚部,它提供的加减乘除运算都是返回新的Complex实例,而不是修改这个实例。不可变对象有很多优点,它只有一种状态,即被创建时的状态,而且前面也提到过,它本质上是线程安全的。

      这里还用到一个小技巧,对频繁使用的值,为它们提供公有的静态final常量。

      还有一种构建不可变类的常用方法,让类的构造器私有化,并添加上公有静态工厂方法,前面也提到过。

      String类就是不可变类一个典型例子。但是细心的读者肯定会发现String类的hash属性不是final类型的,事实上,许多不可变类都拥有一个或多个非final的域,在第一次请求的时候计算出来缓存在这些域中,从而节约了计算所需要的花销。因为对象是不可变的,它的不可变性保证了计算结果相同。

    public final class String{
        private final char value[];
        private int hash;
    
        public int hashCode() {
            int h = hash;
            //只有hash不存在时才去计算
            if (h == 0 && value.length > 0) {
                char val[] = value;
    
                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }
    }

    第16条:复合优先于继承

      简而言之,只有当两者确实存在is-a的关系时,才使用继承。否则,都应该使用复合。对于这一条,应用最典型的例子就是设计模式中的装饰者模式

  • 相关阅读:
    一维数组的 K-Means 聚类算法理解
    c#计算2个字符串的相似度
    一个人开发的html整站源码分享网站就这么上线了
    html页面显示服务器时间
    禁用浏览器自动填充表单解决办法
    布隆过滤器
    (转)二进制与三进制趣题
    随机算法_模拟退火算法
    NAT穿越
    (转)为什么所有浏览器的userAgent都带Mozilla
  • 原文地址:https://www.cnblogs.com/ZhangWanFan/p/5297662.html
Copyright © 2020-2023  润新知