1、Java中的不可变对象和可变对象
(1)不可变类:当你获得这个类的实例的引用之后,你不可以改变这个实例的内容。比如:String,BigInteger,BigDecimal,还有基本数据类型的封装类,这些都是不可变类。用实例来调用方法时,不会改变里面的变量的值。代码:
import java.math.BigInteger; public class BigProblem { public static void main(String[ ] args) { BigInteger fiveThousand = new BigInteger("5000"); BigInteger fiftyThousand = new BigInteger("50000"); BigInteger fiveHundredThousand = new BigInteger("500000"); BigInteger total = BigInteger.ZERO; total.add(fiveThousand); total.add(fiftyThousand); total.add(fiveHundredThousand); System.out.println(total); } }
你可能认为会打印555000,但实际上打印的是0。就是因为你调用方法之后并不能改变这个对象的值。稍微修改下就可以:
import java.math.BigInteger; public class BigProblem { public static void main(String[] args) { BigInteger fiveThousand = new BigInteger("5000"); BigInteger fiftyThousand = new BigInteger("50000"); BigInteger fiveHundredThousand = new BigInteger("500000"); BigInteger total = BigInteger.ZERO; total = total.add(fiveThousand); total = total.add(fiftyThousand); total = total.add(fiveHundredThousand); System.out.println(total); } }
本谜题的教训是:不要被误导,认为不可变类型是可变的。这是一个在刚入门的Java程序员中很常见的错误。公正地说,Java不可变类型的某些方法名促使我们走上了歧途。像add、subtract和negate之类的名字似乎是在暗示这些方法将修改它们所调用的实例。也许plus、minus和negation才是更好的名字。
(2)可变类:当你获得这个类的实例的引用之后,你可以改变这个实例的内容。
2、HashSet要求不能存储相同的对象,HashMap要求不能存储相同的键
(1)hashCode()方法获取给定对象的唯一整数。这个整数被用来确定对象被存储在HashTable类似的结构中的位置。默认的,Object类的hashCode()方法返回这个对象存储的内存地址的编号。
(2)equals(Object)方法
(3)接下来有两个个关于这两个方法的重要规范(我只是抽取了最重要的两个,其实不止两个):
(a)若重写equals(Object obj)方法,有必要重写hashcode()方法,确保通过equals(Object obj)方法判断结果为true的两个对象具备相等的hashcode()返回 值。
(b)如果equals(Object obj)返回false,即两个对象“不相同”,并不要求对这两个对象调用hashcode()方法得到两个不相同的数。
总之,当你覆写equals方法时,一定要记着覆写hashCode方法。
3、0的添加
千万不要在一个整型字面常量的前面加上一个0;这会使它变成一个八进制字面常量。有意识地使用八进制整型字面常量的情况相当少见,你应该对所有的这种特殊用法增加注释。
4、技巧性的问题
(1)Java5中添加了一套位操作方法。
(2)splite方法将字符串按照标志进行分割。
(3)相等的字符串常量也是相同的。
(4)Math.abs(int):“如果其参数等于Integer.MIN_VALUE,那么产生的结果与该参数相同,它是一个负数。” Math.abs不能保证一定会返回非负的结果。如果它的参数是Integer.MIN_VALUE,或者对于long版本的实现传递的是Long.MIN_VALUE,那么它将返回它的参数。