java解惑(谜题56到。库之谜)
java解惑(谜题56到。。库之谜)
谜题56:大问题
你可能认为这个程序会打印出555000。可结果为0。
因为BigInteger的实例是不可变的。String、BigInteger以及包装类也是如此。不能修改它们的值。对这些类型的操作将返回新的实例。
为了得到预想结果,可修改如下:
谜题57:名字里有什么
这里的bug在于Name违反了hashCode约定。无论何时,只要你覆写了equals方法,你就必须同时覆盖hashCode方法。
该集合是根据实例的散列值来选择散列位置的,这个散列值是通过实例的hashCode方法计算出来的。
谜题58:产生它的散列码
下面程序吸取前一个程序的教训,重载了hashCode方法,它输出什么呢?
输出还是false。 注意:在本题中,覆盖了hashCode方法,但没有覆盖equals方法。该类声明的equals方法的参数类型是Name,而不是Object。
HashSet类是使用equals(Object)方法来测试元素的相等性的。
谜题59:差是什么
连续两个元素之差是111,以此类推,其他之差为222。。。。666,777。但是请注意012是一个八进制数。结果输出为27 = 1(0)+14(012与其他元素的差,请注意有正负两个方向)+12(111。。。。666,以及负的)。以0开头的整型字面常量将被解释为八进制数值。
谜题56:大问题
import java.math.BigInteger; public class BigProblem { public static void main(String[] args) { BigInteger i = new BigInteger("5000"); BigInteger j = new BigInteger("50000"); BigInteger k = new BigInteger("500000"); BigInteger total = BigInteger.ZERO; total.add(i); total.add(j); total.add(k); System.out.println(total); //0?? } }
你可能认为这个程序会打印出555000。可结果为0。
因为BigInteger的实例是不可变的。String、BigInteger以及包装类也是如此。不能修改它们的值。对这些类型的操作将返回新的实例。
为了得到预想结果,可修改如下:
total = total.add(i); total = total.add(j); total = total.add(k);
谜题57:名字里有什么
import java.util.HashSet; import java.util.Set; public class Name { private final String first, last; public static void main(String[] args) { Set<Name> s = new HashSet<Name>(); s.add(new Name("Mickey","Mouse")); System.out.println(s.contains(new Name("Mickey","Mouse"))); } public Name(String first, String last) { this.first = first; this.last = last; } public boolean equals(Object o) { if (!(o instanceof Name)) return false; Name n = (Name) o; return n.first.equals(first) && n.last.equals(last); } }
Name a = new Name("Mickey","Mouse"); Name b = new Name("Mickey","Mouse"); System.out.println(a.equals(b)); //true,如果没有重载equals函数,结果为false System.out.println(a==b);//false
这里的bug在于Name违反了hashCode约定。无论何时,只要你覆写了equals方法,你就必须同时覆盖hashCode方法。
该集合是根据实例的散列值来选择散列位置的,这个散列值是通过实例的hashCode方法计算出来的。
谜题58:产生它的散列码
下面程序吸取前一个程序的教训,重载了hashCode方法,它输出什么呢?
import java.util.HashSet; import java.util.Set; public class Name { private final String first, last; public static void main(String[] args) { Set<Name> s = new HashSet<Name>(); s.add(new Name("Mickey","Mouse")); System.out.println(s.contains(new Name("Mickey","Mouse"))); } public Name(String first, String last) { this.first = first; this.last = last; } public boolean equals(Name n) { return n.first.equals(first) && n.last.equals(last); } public int hashCode(){ return 31*first.hashCode()+last.hashCode(); //只要重载即可, } }
输出还是false。 注意:在本题中,覆盖了hashCode方法,但没有覆盖equals方法。该类声明的equals方法的参数类型是Name,而不是Object。
HashSet类是使用equals(Object)方法来测试元素的相等性的。
谜题59:差是什么
import java.util.HashSet; import java.util.Set; public class Difference { public static void main(String[] args) { int vals[] = {789,678,567,456,345,234,123,012}; for(int k = 0 ;k<vals.length;k++) System.out.println(vals[k]); Set<Integer> s = new HashSet<Integer>(); for(int i =0 ;i<vals.length;i++){ for(int j = 0;j<vals.length;j++){ s.add(vals[i]-vals[j]); } } System.out.println(s.size()); } }
连续两个元素之差是111,以此类推,其他之差为222。。。。666,777。但是请注意012是一个八进制数。结果输出为27 = 1(0)+14(012与其他元素的差,请注意有正负两个方向)+12(111。。。。666,以及负的)。以0开头的整型字面常量将被解释为八进制数值。