在Java SE1.5中,增加的一个新的特性:泛型。何谓泛型呢?通俗的说,就是泛泛的指定对象所操作的类型,而不像常规方式一样使用某种固定的类型去指定。泛型的本质就是将所操作的数据类型参数化,也就是说,该数据类型被指定为一个参数。这种参数类型可以使用在类、接口以及方法定义中。用于解决安全问题,是一个安全机制。
在以往的J2SE中,没有泛型的情况下,通常是使用Object类型来进行多种类型数据的操作。这个时候操作最多的就是针对该Object进行数据的强制转换,而这种转换是基于开发者对该数据类型明确的情况下进行的(比如将Object型转换为String型)。倘若类型不一致,编译器在编译过程中不会报错,但在运行时会出错。
所以定义泛型的好处:
(1)将运行时期出现的问题ClasscastEception,转移到了编译时期。方便于程序员解决问题,让运行事情问题减少,增强安全性。
(2)在运行时所有的转换都是强制的,隐式的,避免了强制转换。
(3)提高代码的重用率。
泛型格式:通过<>未定义要操作的引用数据类型。
在使用Java提供的对象时,什么时候使用泛型?
通常在集合框架中很常见。只要见到<>就要定义泛型。
<>里面是用来接收类型的,当使用集合时,将集合要存储的数据类型作为参数传递到<>中即可。
泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定。
为了让不同方法操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。
注意:静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据类型不明确,可以将泛型定义在方法上(泛型定义在返回值前修饰符后)
1、泛型的参数类型只能是引用类型,而不能是简单类型。
2、可以声明多个泛型参数类型,比如>
3、泛型的参数类型可以使用extends语句,例如
4、泛型的参数类型可以使用super语句,例如< T superchildclass>。
5、泛型还可以使用通配符,例如 extends ArrayList>
使用extends语句将限制泛型参数的适用范围。例如:
super语句的作用与extends一样,都是限制泛型参数的适用范围。区别在于,super是限制泛型参数只能是指定该class的上层父类。
例如
Vector extends 类型1> x = new Vector<类型2>();
类型1指定一个数据类型,那么类型2就只能是类型1或者是类型1的子类
Vector extends Number> x = new Vector
Vector extends Number> x = new Vector
Vector super 类型1>x = new Vector<类型2>();
类型1指定一个数据类型,那么类型2就只能是类型1或者是类型1的父类
Vector super Integer> x = new Vector
Vector super Integer> x = new Vector
注意:限定通配符包括自己
Collection是集合类的一个顶级接口,其直接继承接口有List与Set,而Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。
使用sort方法可以根据元素的自然顺序对指定列表按升序进行排序。列表中的所有元素都必须实现 Comparable 接口。此列表内的所有元素都必须是使用指定比较器可相互比较的。
public static
根据元素的自然顺序 对指定列表按升序进行排序。
public static
根据指定比较器产生的顺序对指定列表进行排序。
public static
根据元素的自然顺序,返回给定collection 的最大元素。
public static
根据指定比较器产生的顺序,返回给定collection 的最大元素。
public static
根据元素的自然顺序 返回给定 collection 的最小元素。
public static
根据指定比较器产生的顺序,返回给定collection 的最小元素。
public static
使用二分搜索法搜索指定列表,以获得指定对象。
public static
使用二分搜索法搜索指定的比较器对列表进行排序的列表,以获得指定对象。
原理:
public static int binarysearch(List list,String key,Comparator com){
int max=list.size()-1;
int min=0;
while (min<=max){
int mid=(min+max)>>1;
String str=list.get(mid);
//int num=str.compareTo(key);
int num=com.compare(str, key);
if (num>0)
max=mid-1;
else if (num<0)
min=mid+1;
else return mid;
}
return -min-1;
}
使用指定元素替换指定列表中的所有元素。
//练习:使用指定元素替换指定列表中的指定元素。
class Test4{
public static void main(String[] args){
List< String> list= new ArrayList< String>();
list.add( "a" );
list.add( "bbb" );
list.add( "www" );
System.out.println(list);
fillDemo(list,"aaa",1,2);
System.out.println(list);
}
public static void fillDemo(List list,String str,int start,int end){
//第一种方式:
List< String> li=list.subList(start, end);
Collections. fill(li,str);
ListIterator< String> ls=list.listIterator();
ListIterator< String> lis=li.listIterator();
while (ls.hasNext()){
String s=ls.next();
while (lis.hasNext()){
String s1=lis.next();
s=s1;;
}
}
}
//第二种方式:
// for( int x=start;x<=end-1;x++){
// list.set(x,str);
// }
}
public static
使用另一个值替换列表中出现的所有某一指定值。
public static void reverse(List>list)
使用Reverse方法可以根据元素的自然顺序对指定列表按降序进行排序。
public static
返回一个比较器,它强行逆转实现了Comparable 接口的对象 collection 的自然顺序。
public static
返回一个比较器,它强行逆转指定比较器的顺序。
public Test4(){
public static void main(String[] args)
{
String s="aaaa";
Set al=new TreeSet(new MyCompara());
al.add("bbb");
al.add("aaaa");
al.add("dddaa");
al.add("aabcaa");
System.out.println(al);
//Collections.sort(al);
//Test4.fillDemo(al,"zzz",0,2);
//Collections.replaceAll(al,"aaa","zzz");
System.out.println(al);
//int i=Test4.binarysearch(al,"ddd");
//String s=al.get(i);
//System.out.println(s);
}
}
class MyCompara implements Comparator
{
public int compare(String s1,String s2){
int num=new Integer(s1.length()).compareTo(new Integer(s2.length()));
if(num==0)
return s1.compareTo(s2);
return num;
}
}
public static
用两个参数,一个目标 List 和一个源 List, 将源的元素拷贝到目标,并覆盖它的内容。目标 List 至少与源一样长。如果它更长,则在目标 List 中的剩余元素不受影响。
public static void swap(List> list,int i, int j)
在指定列表的指定位置处交换元素。(如果指定位置相同,则调用此方法不会更改列表。)
混排算法所做的正好与 sort 相反: 它打乱在一个 List 中可能有的任何排列的踪迹。也就是说,基于随机源的输入重排该 List, 这样的排列具有相同的可能性(假设随机源是公正的)。这个算法在实现一个碰运气的游戏中是非常有用的。例如,它可被用来混排代表一副牌的 Card 对象的一个 List 。另外,在生成测试案例时,它也是十分有用的。
public static void shuffle(List>list)
使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。
public static void shuffle(List>list, Random rnd)
使用指定的随机源对指定列表进行置换。所有置换发生的可能性都是相等的,假定随机源是公平的。
java.util.Arrays类能方便地操作数组,它提供的所有方法都是静态的。
基本操作:
public static
为什么数组转换为集合?
可以使用集合里的特定方法。
注意:将数组变成集合后,不可以使用集合的增删方法,因为数组的长度是固定的,如果增删的话会出现lang.UnsupportedOperationException异常。
asList接受的参数是一个泛型的变长参数,我们知道基本数据类型是无法发型化的,也就是说8个基本类型是无法作为asList的参数的, 要想作为泛型参数就必须使用其所对应的包装类型。
public Object[] toArray()
public T[] toArray(T[] a)
public static void theard_2(){
List< String> list= new ArrayList< String>();
list.add( "aaa" );
list.add( "bad" );
list.add( "dgfg" );
String[] s= new String [list.size()];
String [] arr=list.toArray(s);
System. err .println(Arrays.toString(arr));
}
注意:当指定类型的数组长度,小于集合的长度时,那么该方法会创建一个新的数组,长度为集合的长度。
当指定类型的数组长度,大于集合的长度时,就不会创建新的数组,而是使用传递进来的数组。
为什么将集合转换为数组?
为了限定对元素的操作。
for(数据类型 变量名:被遍历的集合(Collection)或者数组){ }
for循环和Interator迭代器有什么区别?
对集合进行遍历,只能获取集合的元素,不能对集合进行操作。
迭代器除了遍历,还可以进行remove集合元素的操作。
如果使用ListIterator,还可以在遍历的时候对集合中的元素进行增删改查操作。
传统的for和高级的for有什么区别?
高级的for有一个局限性,必须由遍历的目标。
JDK1.5版本出现的新特性。
方法的可变参数,在使用时可变参数一定要放在最后面。
//虽然少定义了多个方法,但是每次都需要new数组进去。
public static void theard_4( int[] i){
System. err .println(Arrays.toString(i));
}
//可变参数,其实就是上一个数组的简化形式。不用每次手动建立数组对象,
//只要将要操作的元素作为参数传递进去即可,隐式的将这些元素封装成数组。
public static void theard_5( int... i){
System. err .println(Arrays.toString(i));
}
public static void main(String[] args) {
int [] i={1,2,3};
int [] i1={1,2,3,4,5};
theard_4(i1);
theard_5(1,5,6);
}
例如:import staticjava.util.Arrays.*;导入的是Arrays这个类中所有的静态成员。
注意:当类的方法重名时,需要指定具体的包名。
当方法重名时,指定所属的对象,或类。