1.不可变类型的问题
问题:
BigInteger i = 1;
BigInteger j = 1;
i.add(j);后i是多少? 1
分析:
(1)不可变类型种类:String、BigDecimal、BigInteger和各种包装器类型都是不可变类型。
(2)对于String不可变的特性在我另一篇博文中说到。
(3)比如BigInteger的add方法,并不会改变两个操作数即现有实例,而是返回新的实例。
结论:
在调用不可变对象的方法时,如果对于看起来是对对象进行改变的方法,则现有实例并不会改变,而是返回一个新的实例。
import java.math.*;
public class PuzzleDemo56{
public static void main(String args[]){
BigInteger five = new BigInteger("5");
BigInteger six = new BigInteger("6");
BigInteger total = BigInteger.ZERO;
total = five.add(six);
System.out.println("5 + 6 = "+total);
}
}
2.HashSet中覆写hashCode的重要性
在HashSet中寻找某个对象需要两个步骤:
(1)通过计算hashCode方法计算散列码,并对应到某个数组索引。
(2)通过数组索引对应的链表遍历,调用equals方法查找是否已经存在这个对象。
结论:
因此在HashSet中hashCode和equals方法缺一不可,当然在一般的类中,如果覆写了equals方法,就必须覆写hashCode方法。
import java.util.*;
public class PuzzleDemo57{
private final String first,last;
public PuzzleDemo57(String first,String last){
this.first = first;
this.last = last;
}
@Override
public boolean equals(Object o){
if(!(o instanceof PuzzleDemo57))
return false;
PuzzleDemo57 n = (PuzzleDemo57)o;
return n.first.equals(first) && n.last.equals(last);
}
@Override
public int hashCode(){
return 13 * first.hashCode() + 27 * last.hashCode();
}
public static void main(String args[]){
Set<PuzzleDemo57>s = new HashSet<PuzzleDemo57>();
s.add(new PuzzleDemo57("xia","zdong"));
System.out.println(s.contains(new PuzzleDemo57("xia","zdong")));
}
}
3.八进制表示问题
问题:int i[] = {012,123,234}; 中 i[1]-i[0]结果是什么? 113
分析:
(1)八进制表示:以0开头的整形字面常量。
结论:
千万不要在一个整型字面常量前加一个0.
import java.util.*;
public class PuzzleDemo59{
public static void main(String args[]){
int vals[] = {789,678,567,456,345,234,123,12};
Set<Integer>diffs = new HashSet<Integer>();
for(int i=0;i<vals.length;i++){
for(int j=i;j<vals.length;j++){
int tmp = vals[i] - vals[j];
diffs.add(tmp);
System.out.println(tmp);
}
}
}
}
4.打印数组的巧妙方法
问题:如果编写一个方法打印数组,接收一个数组,但却不知道数组的维度,该怎么办? 库方法
分析:
在Arrays类中有一个deepToString()方法,如果传递的是数组,则将打印数组中的内容。
结论:
要了解类库中的方法。
import java.util.*;
public class PuzzleDemo60{
public static void main(String args[]){
String[]strs =
{"spam","sausage","spam","bacon","spam"};
List<String> list = Arrays.asList(strs);
List<String> list2 = deleteMore(list);
System.out.println(list2);
int[][]s = new int[3][2];
s[0][0] = 1;
s[0][1] = 1;
s[1][0] = 1;
s[1][1] = 1;
s[2][0] = 1;
s[2][1] = 1;
System.out.println(Arrays.deepToString
(s));
}
public static List<String> deleteMore
(List<String> list){
return new ArrayList<String>(new
LinkedHashSet<String>(list));
}
}
5.如果要在List中去除重复元素,则可以把他放到Set中,则会自动去除。
6.Integer.bitCount(int i)返回i变成二进制后被置位的位数。
7.Date和Calendar的一些规定
(1)在这两个类中,月份都是从0开始计数,即一月是0。
(2)Date的方法基本都已经过时,所以不要使用。
(3)Calendar cal = Calendar.getInstance();创建一个实例。
(4)cal.set(int year,int mon,int day);设置时间。
import java.util.*;
public class PuzzleDemo61{
public static void main(String args[]){
Calendar cal = Calendar.getInstance();
cal.set(1999,Calendar.DECEMBER,31);
System.out.print(cal.get(Calendar.YEAR)+" ");
System.out.println(cal.get(Calendar.DAY_OF_MONTH));
}
}
8.Math.abs(i)一定返回非负数?
问题:Math.abs(Integer.MIN_VALUE)返回什么? Integer.MIN_VALUE.
分析:
(1)一般情况下,返回的是非负数。
(2)当参数为Integer.MIN_VALUE时,则返回是其本身。
import java.util.*;
public class PuzzleDemo64{
public static void main(String args[]){
int min = Math.abs(Integer.MIN_VALUE);
System.out.println(min); //打印的仍是Integer.MIN_VALUE.
final int MODULUS = 3;
int[] histogram = new int[MODULUS];
int i = Integer.MIN_VALUE;
do{
histogram[mod(i,MODULUS)]++;
}while(i++!=Integer.MAX_VALUE);
for(int j=0;j<MODULUS;j++){
System.out.println(histogram[j]+" ");
}
}
public static int mod(int i,int modulus){
int result = i%modulus;
return result<0?result+modulus: result;
}
}
9.惯用法比较器真的正确?
问题:
Comparator comp = new Comparator<Integer>(){ public int compare(Integer i,Integer j){ return i-j; } } |
这种传统的比较器真的正确吗? 不!
分析:
(1)这种惯用法是不合理的,因为i-j可能会溢出。
结论:
Comparator<Integer> comp = new Comparator<Integer>(){ public int compare(Integer i,Integer j){ return i<j?-1:((i==j)?0:1); } }; |
这种比较器是没有问题的。
因此千万不要使用基于减法的比较器。
import java.util.*;
public class PuzzleDemo65{
public static void main(String args[]){
Integer[]arr = {Integer.MIN_VALUE,2};
Comparator<Integer> oldComp = new Comparator<Integer>(){
public int compare(Integer i,Integer j){
return i-j;
}
};
Comparator<Integer> comp = new Comparator<Integer>(){
public int compare(Integer i,Integer j){
return i<j?-1:((i==j)?0:1);
}
};
Arrays.sort(arr,oldComp);
System.out.println(arr[0]+" "+arr[1]);
Arrays.sort(arr,comp);
System.out.println(arr[0]+" "+arr[1]);
}
}