库之谜总结

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]);
		
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值