-
单例模式(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;
参考:梦想风暴