一 递归:
使用递归必须遵循四个基本法则:
1 基准情形
必须要有某些基准情形,它无需递归就能解出来
2 不断推进
对于那些需要递归求解的情形,每一次递归调用都必须是状况朝着一种基准状况推进
3 设计法则
假设所有的递归调用都能运行
4 合成效益法则
在求解同一问题时,切勿在不同的递归中做重复性的工作。比如在计算斐波那契数列时,使用递归并不好,原因正是由于第四条法则,会重复计算。
二 协变:
抽象类 Number
是 BigDecimal
、BigInteger
、Byte
、Double
、Float
、Integer
、Long
和Short
类的超类。
协变是指一个类型随着它关联的类型一起变化,有点抽像,java中体现协变的包括两点:
1 数组
数组是会协变的,如果 A 是 B 的超类,则 A[] 也是 B[] 的超类,所有需要 A[] 的地方都可以用 B[] 代替。
public class Test2 {
public static void main(String[] args){
Integer[] ints=new Integer[1];
ints[0]=99;
show(ints);
}
static void show(Number[] ns){
System.out.println(Arrays.toString(ns));
}
}
2 泛型
泛型不允许协变
如果 A 是 B 的超类,则 List<A> 和 List<B> 无关,需要 List<A> 的地方不可以用 List<B> 代替。
public class Test2 {
public static void main(String[] args) {
List<Integer> ints = new ArrayList<Integer>();
//incompatible type
show(ints);
}
static void show(List<Number> ns) {
System.out.println(ns);
}
}
解决办法:在Java 5中使用通配符来解决这个问题。
public class Test2 {
public static void main(String[] args) {
List<Integer> ints = new ArrayList<Integer>();
show(ints);
}
static void show(List<? extends Number> ns) {
System.out.println(ns);
}
}
3 泛型方法:
在方法中加泛型的时候 是加在返回值之前,什么时候需要在方法中加尖括号泛型:
有以下三点:满足一点就需要
1)该特定类型用作返回类型
2)该特定类型用在不止一个参数类型中
3)该类型用于声明一个局部变量
public static <T> boolean contains(T[] a,T b)
{
for(T t:a)
{
if(b.equals(t))
return true;
}
return false;
}
尖括号中的叫做类型界限 使用特点在数据结构java描述书中P15
补充:http://blog.sina.com.cn/s/blog_617a491c0100eox7.html