泛型Generic
1.解决的问题
-
解决存储的安全性问题
-
解决获取数据元素时,需要类型强转的问题
public class TestGeneric { //在集合中没有使用泛型的时候 public static void main(String[] args) { List list=new ArrayList(); list.add(89); list.add(90); list.add(69); //1.没有使用泛型,任何Object类型的数据都会添加进集合 //因此我们可以设置泛型使其只添加int类型的数据 list.add(new String("aa"));//添加了不同类型的数据 for(int i=0;i<list.size();i++){ int score=(Integer) list.get(i); System.out.println(score);//因为添加了String类型数据因此会出现ClassCastException 类型转化异常 } } }
使用泛型:
//查看List public interface List<E> extends Collection<E>
Map<String,Integer> map=new HashMap<String,Integer>(); map.put("AA",68); map.put("BB",68); map.put("CC",68); map.put("DD",90); Set<Map.Entry<String,Integer>> mapSet = map.entrySet(); for(Map.Entry<String,Integer> o:mapSet){ System.out.println(o.getKey()+"---->"+o.getValue()); }
2.自定义泛型类,泛型接口,泛型方法
public class application {
//自定义泛型的使用
public static void main(String[] args) {
//1.当时实例化泛型类的对象时,需要指明泛型的类型,当指明后,对应类中的所有泛型的位置都会变为指定的类型。
//2.如果实例化的时候没有指明泛型中的类型,则默认是Object类型。
Order<Boolean> order=new Order<>();
order.setT(true);
order.add();
List list=order.list;
Order<Boolean> order1=new Order<>();
order1.setT(false);
order1.add();
list.addAll(order1.list);
System.out.println(list);
System.out.println(order.getT());
//此时不用再指明泛型的类型
SubOrder subOrder=new SubOrder();
//已经指明list中的元素是Integer
subOrder.setT(12);
subOrder.add();
List<Integer> list2=subOrder.list;
System.out.println(list2);
}
}
//继承泛型类或泛型接口时,可以指明泛型的类型
class SubOrder extends Order<Integer>{
}
class SubOrder1<T> extends Order<T>{
}
//泛型的应用,可以写一些操作数据库的通用方法
public class Dao<T>{
public void add(T t){
//....比如说网数据库中添加某一个表的记录
}
public T get(){
//....返回数据库中某个表的记录
}
}
//通过继承,表明泛型的具体类型
public class CustomerDao extends Dao<Customer>{
}
泛型方法(通过Collection仿写)
自定义泛型方法的格式:
修饰符 <声明自定义泛型的类型> 返回值类型 函数名(使用自定义的泛型…)
public <E> E getE(E e){ //放在Order类中
return e;
}
//调用
//当通过对象调用泛型方法时,指明泛型的类型
Integer i=order.getE(34);
Double j=order.getE(3.4);
//实现数组到集合的复制 放在Order类中
public <E> List<E> fromArrayTOList(E[] e,List<E> list){
for(E e1:e){
list.add(e1);
}
return list;
}
//调用
Integer[] in =new Integer[]{3,4,6};
List<Integer> list=new ArrayList<>();
List<Integer> list2=order.fromArrayTOList(in,list);
3.泛型与继承的关系
public void test(){
Object obj=null;
String str="AA";
obj=str;//String是Object的子类,可以将子类对象赋给父类
Object obj1=null;
String[] str1=new String[]{"AA","BB","CC"};
obj1=str1;
//但以下实现不成立,因为List<String>不是List<Object> 的子类
List<Object> list=null;
List<String> list2=new ArrayList<>();
list=list2;
}
4.通配符 ?
例如List…List都是List<?>的子类,而List…List并列
List<?> list=null;
List<Object> list1=new ArrayList<>();
List<String> list2=new ArrayList<>();
list=list1;
list=list2;
//所以可以看出List<?>是List<Object> List<String>的父类
分析:
public void show(List<Object> list){
//...
}
show(list1);
show(list2);//此使用不正确,因为List<Object>和List<String>并列的
//但如果public void show(List<?> list){} 则两个show()都可以
Boolean addAll(Collection<? extends E> c);
//此方法的参数可以传入E和E的子类。E在声明对象的时候确定
List<? extends Number> list3=null;
List<Integer> list4=new ArrayList<>();
list3=list4;
List<? super Number> list5=null;
list5=list1 //list1 泛型是Object类型的
List<String> list=new ArrayList<String>();
list.add("AA");
list.add("BB");
List<?> list1=list;
//可以读取声明为通配符的集合类的对象,但不能写
Iterator<?> it=list1.iterator();
while(it.hasNext()){
System.out.println(it.Next());
}
//但不允许写,无法向声明为通配符的集合中添加对象
list1.add("CC");//因为通配符不知道添加什么类型,但是null可以添加