1类属
总称是什么? 为什么要使用泛型?
泛型类型,即“参数化类型”。 说到参数,最常见的是在定义方法时传递物理参数,在调用方法时传递物理参数。 参数类型如何理解? xfdxx是类型从原始具体类型参数化而来的,类似于方法中的变量参数。 此时,类型也被定义为参数格式(也称为类型参数),然后在使用/调用时传递具体的类型(类型实参数)。
泛型类型的本质是参数化类型。 在不创建新类型的情况下,由泛型类型指定的不同类型控制形状参数的特定限制类型。 这意味着,在一般用途中,所操作的数据类型被指定为参数。 此参数类型可用于类、接口和方法中,分别称为泛型类、泛型接口和泛型方法。
【例】没有通用性的例子
ArrayList list=new ArrayList (;
list.add(adddff );
list.add('123 );
list.add(newinteger(123 ) );
Iterator it=list.iterator (;
while(it.Hasnext ) ) ) )。
stringstr=(string ) it.next );
system.out.println(str;
}
Java.lang.classcastexception : Java.lang.integercannotbecasttojava.lang.string
为了解决这个问题,JDK1.5引入了解决安全问题的通用新机制,是一种安全机制。
通用的出现把执行时期的问题转移到了编译时期。 同时避免了强制转换的麻烦。
【例】具有通用性
ArrayList list=new ArrayList (;
list.add(adddff );
list.add('123 );
list.add(newinteger(123 ) );
通用性会导致编译器报告错误。 add(Java.lang.string ) inarraylistcannotbeappliedto (Java.lang.integer )。
1.1通用用法
通用有三种使用方法:通用类、通用接口和通用方法。
通用类泛型用于定义类,称为通用类。 泛型类型允许对一组类的操作向外开放同一接口。 最典型的是各种容器类,如List、Set和Map。
通用类的最基本写法: class类名{}
【例】最常见的通用类
公共类通用{
私有密钥;
公共通用(tkey ) {
this.key=key;
}
public T getKey () }
返回t;
}
}
泛型类型参数是引用数据类型,而不是基本数据类型。
例如,如果是class Generic{},下面的t都会自动成为字符串类型。
泛型类不需要传递类型参数。 泛型类仅用于限制传递的数据类型。 不写的话一样没有问题。
【例】通用性不适用
generic generic=new generic (' 11111 ); 通用通用1=新通用(4444 ); generic generic2=new generic (55.55 generic generic3=new generic (false );
Log.d (“通用测试”、“key is ' generic.getKey ) );
Log.d (“通用测试”、“key is ' generic1.getKey ) );
Log.d (“通用测试”、“key is ' generic2.getKey ) );
Log.d (“通用测试”、“key is ' generic3.getKey ) );
D/通用测试: key is 111111
D/通用测试: key is 4444
D/通用测试: key is 55.55
D/通用测试:密钥is false
通用接口
通用接口与通用类的定义和使用基本相同。 通用接口常备于各种类型的生产器中。
【例】通用接口的定义
公共接口生成器TIC {
公共t next (;
}
如果没有将通用参数传递给实现通用接口的类:
【例】
//*
*如果未传递通用部件参数,则声明类时,必须同时添加通用部件类的声明,就像定义通用部件类一样
*即class fruit生成器
implements Generator{* 如果不声明泛型,如:class FruitGenerator implements Generator,编译器会报错:"Unknown class"
*/
class FruitGenerator implements Generator{
@Override
public T next() {
return null;
}
}
当实现泛型接口的类,传入泛型实参时:
/**
* 传入泛型实参时:
* 定义一个生产器实现这个接口,虽然我们只创建了一个泛型接口Generator
* 但是我们可以为T传入无数个实参,形成无数种类型的Generator接口。
* 在实现类实现泛型接口时,如已将泛型类型传入实参类型,则所有使用泛型的地方都要替换成传入的实参类型
* 即:Generator,public T next();中的的T都要替换成传入的String类型。
*/
public class FruitGenerator implements Generator {
private String[] fruits = new String[]{"Apple", "Banana", "Pear"};
@Override
public String next() {
Random rand = new Random();
return fruits[rand.nextInt(3)];
}
}
泛型方法
【示例】
/**
* 泛型方法的基本介绍
* @param tClass 传入的泛型实参
* @return T 返回值为T类型
* 说明:
* 1)public 与 返回值中间非常重要,可以理解为声明此方法为泛型方法。
* 2)只有声明了的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
* 3)表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
* 4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
*/
public T genericMethod(Class tClass)throws InstantiationException ,
IllegalAccessException{
T instance = tClass.newInstance();
return instance;
}
2 集合(ArrayList、LinkedList、Vector)
为什么会出现集合类?
面向对象语言对事物的体现都是以对象的形式。所以为了方便对多个对象的操作,就对对象进行储存,集合就是储存对象最常用的而一种方式。
数组和集合类同时容器,有何不同?
数组虽然也可以储存对象,但长度是固定的;集合长度是可变的的。 数组中可以储存基本数据类型,集合只能储存对象。
集合类的特点: 集合只用于储存对象,集合长度是可变的,集合可以储存不同类型的对象。
Collection集合体系
Collection
List Set
ArrayList HashSet
LinkedList TreeSet
Vector
Collection是集合容器中的根接口。
为什么会出现这么多的容器呢?
每一个容器对数据储存的方式都有相同。 这个储存方式称为数据结构。
List:元素是有序的,元素可以重复.
List集合特有的方法:
增
add(index, element);
addAll(index, Collection);
删
remove(index);
改
set(index, element);
查
get(index);
subList(from, to);
listIterator();
List集合特有的迭代器ListIterator是Iterator的子接口
在迭代时,不可以通过集合对象的方法操作集合中的元素。
会发生java.util.ConcurrentModificationException异常
所以,在迭代时只能用迭代器的方法操作元素,可以Iterator方法是有限的,
只能对元素进行判断,取出,删除的操作,
如果想要其他操作如添加,修改等,就需要通过子接口ListIterator来实现。
List接口:有三个子类
ArrayList LinkedList Vector
底层实现 数组 双向链表 数组
ArrayList:查询快,增删稍慢。
LinkedList:增删快,查询慢
Vector: 线程安全,效率比ArrayList低。被ArrayList取代了。
LinkedList特有方法
addFirst();
addLast();
在此列表的开头/末尾插入指定的元素。
getFirst();
getLast();
获取元素,但不删除
removeFirst();
removeLast();
获取元素,元素被删除
如果集合中没有元素,会出现noSuchElementException异常
在JDK1.6出现了替代方法,
offerFirst();
offerLast();
在此列表的开头/末尾插入指定的元素。
peekFirst();
peekLast();
获取元素,但不删除元素,如果没有元素,会返回null
pollFirst();
pollLast();
获取元素被删除;如果此列表为空,则返回 null。
ArrayList:
创建一个储存字符串的ArrayList对象:
ArrayList list = new ArrayList();
创建一个储存日期的ArrayList对象:
ArrayList list2 = new ArrayList();
JDK1.7以后,下述表达式
ArrayList list = new ArrayList();
可以简化为: ArrayList list = new ArrayList<>();
因为编译器有一个新的feature叫做类型推断(type inference), 能够从变量声明推断类型。
【示例】ArrayList常用的方法
public static void method_1(){
//创建一个集合容器,使用Collection接口的子类ArrayList
ArrayList list = new ArrayList<>();
//添加元素
list.add("java01");
list.add("java02");
list.add("java03");
list.add("java04");
list.add("java05");
//获取个数,集合长度
sop("size: "+ list.size());
//删除元素
list.remove("java01");
sop(list);
//清空集合
list.clear();
sop(list);
//判断元素
sop("java03是否存在: "+ list.contains("java03"));
sop("集合是否为空呀?"+ list.isEmpty());
}
public static void sop(Object obj){
System.out.println(obj);
}
遍历ArrayList集合中的元素
//遍历元素,迭代器遍历
Iterator iterator = list.iterator();
while(iterator.hasNext()){
Object obj = iterator.next();
System.out.println(obj);
}
//方式二
for(Iterator iterator1 = list.iterator(); iterator1.hasNext();){
System.out.println(iterator1.next());
}
//for循环遍历
for(int i 0; i < list.size(); i++){
sop("list("+ i +")="+list.get(i)+", ");
}
//for-each循环
for(Object obj : list){
System.out.println(obj);
}