博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Singleton 单例模式和Scala中的单例对象
阅读量:6329 次
发布时间:2019-06-22

本文共 2419 字,大约阅读时间需要 8 分钟。

  hot3.png

  • 单例模式(JAVA vs Scala)

Singlton是一种为许多人熟知的设计模式,到了Scala这里,它成了语言的一部分,换句换说,我们不必像Java那样费劲的自己实现。下面就是一个Singleton:

object Singleton {
  def show = println("I am a singleton")
}
(Singleton.scala)
这里,我们用object进行声明,它会创建这个一个类,这个类只有一个实例,名字就叫Singleton。我们可以这样使用它:
  Singleton.show
编译一下:
  scalac Singleton.scala
不同于类的编译,Singleton编译出两个.class文件:Singleton.class和Singleton$.class。其实,真正称得上是Singleton的类是Singleton$,反编译一下,就可以看出来:
  javap -c Singleton$
输出如下:
public final class Singleton$ extends java.lang.Object implements scala.ScalaObject{
public static final Singleton$ MODULE$;
public static {};
  Code:
   0:    new    #10; //class Singleton$
   3:    invokespecial    #13; //Method "<init>":()V
   6:    return
public void show();
  ...
}
其中,MODULE$是这个类唯一的实例,这个实例是在static块创建出来的。所以,Singleton.show这样的语句到了JVM的层面,就会变成这样:
  Singleton$.MODULE$.show();
不知道你是否注意到,这个类里根本没有构造函数,换句话说,站在使用者的角度,我们根本就没有机会为这个类创建对象。如果你还不太适应这个没有构造函数的世界,可以参考《》。
我们都知道,javac会为没有构造函数的类生成一个缺省的构造函数,所以,在Java代码里,如果我们想实现Singleton必须显式声明出一个private的构造函数。而scalac绕过了javac直接生成字节码,它给出了一个用Java语言无法实现的Singleton方案。
如果说Singleton$是真正的Singleton实现,那么还有个Singleton类是干什么的呢?先来反编译,看看它做了些什么:
  javap -c Singleton

输出如下:

public final class Singleton extends java.lang.Object{
public static final void show();
  Code:
   0:    getstatic    #11; //Field Singleton$.MODULE$:LSingleton$;
   3:    invokevirtual    #13; //Method Singleton$.show:()V
   6:    return
}

我们看到了,这里有一个方法里同样有一个show方法,不同与Singleton$里的实现,它是static的,而它几乎是完全的透传,也就是说,这个方法实现是:
  public static final void show() {
    Singleton$.MODULE$.show();
  }

  • 使用Scala求校验和

import scala.collection.mutable.Map

class ChecksumAccumlator {

    private var sum=0

    def add(b:Byte):Unit=sum+=b

    def checksum(): Int = ~(sum & 0xFF)+1

}

object ChecksumAccumlator {

    private val cache = Map[String,Int]()

    def calculate(s:String):Int =

        if(cache.contains(s))

            cache(s)

        else{

            val acc = new ChecksumAccumlator

            for(c <- s)

                acc.add(c.toByte)

            val cs = acc.checksum()

            cache += (s -> cs)

            cs

        }

}

 

import ChecksumAccumlator.calculate

object Summer{

    def main(args : Array[String]) {
        for(arg <- args)
            println(arg + ": " + calculate(arg))
    }

  • 计算机内存的数据都是以补码的形式存放的

因为用吧补码表达一个数时,0的代码是唯一的。同时,补码进行运算时,数的符号不用单独处理,通过用补码进行表示,就可以把减法运算化为加法运算。

  • 补码取反加一与补码减一取反相同的证明

补码取反加一与补码减一取反相同的证明:

个位是1:

取反加一与减一取反都是从1变成为0,再变为1;
取反加一:取反从1变成为0,加一再变为1;
减一取反:减一从1变成为0,取反再变为1;
个位是0:说明该数的形式必为:1…(1或者0)…1(m个0); 其中(m的值为1~N),第(m+1)位的值为1,所以主要看前m+1位(即100…00)的原码与补码转换情况:
取反加一:取反前m+1位变为011…11,加一再变为100…00;
减一取反:减一前m+1位变为011…11,加一再变为100…00;

 

参考:梦想风暴

转载于:https://my.oschina.net/liango/blog/69663

你可能感兴趣的文章
理解 IEnumerable 与 IEnumerator
查看>>
NHibernate 2.0 Beta 1 Released和一些工具
查看>>
【每天一个Linux命令】12. Linux中which命令的用法
查看>>
软件接口数据一致性机制
查看>>
微服务架构介绍和RPC框架对比
查看>>
Debian下使用OpenLDAP 管理端
查看>>
泛型排序器TComparer
查看>>
9个offer,12家公司,35场面试,从微软到谷歌,应届计算机毕业生的2012求职之路...
查看>>
创建符合标准的、有语意的HTML页面——ASP.NET 2.0 CSS Friendly Control Adapters 1.0发布...
查看>>
Adobe驳斥Flash过度耗电论 称HTML5更耗电
查看>>
No!No!No! It's not fashion!
查看>>
艰困之道中学到的经验教训
查看>>
Vue 组件库 HeyUI@1.16.0 更新日志
查看>>
互联网生态建设落地五大挑战——保险科技生态建设 ...
查看>>
进行短视频app开发工作时,可以加入它来保护青少年 ...
查看>>
Rxjs 学习推荐
查看>>
25G DAC无源高速线缆和25G光模块之间的区别
查看>>
乐乐茶完成近2亿元Pre-A轮融资,祥峰投资领投
查看>>
clickhouse修改时区
查看>>
CSS_定位
查看>>