一泛型
泛型: 标识着集合中保存的元素是什么类型.
泛型的好处:
1.操作数据更加安全(规范集合中能保存的数据)
2.可以避免向下强转类型的麻烦
3.将运行时的错误转到编译时报错
--泛型类
在类的声明上添加泛型 ,使用字母 可以随意一个字母,不考虑大小写
public class Worker<Z> { // 声明成员变量 private Z z; //声明成员方法 set get public Z getZ() { return z; } public void setZ(Z z) { this.z = z; }
如上,我们通过泛型定义,能够使代码得到复用.我们可以将Z 替换成任何我们想要的类型
Worker<Integer> integerWorker = new Worker<Integer>(); Worker<Double> doubleWorker = new Worker<Double>(); Worker<String> stringWorker = new Worker<String>();
类上声明的泛型 会在创建对象时 被赋值真正的类型.另外一个类中可以声明对个泛型
--泛型方法
声明方式 :声明一个泛型方法很简单,只要在返回类型前面加上一个类似<W>
的形式就行了:
public<W> void fun( W w) { System.out.println(w); }如果你在方法声明了新的泛型,该泛型会在该方法调用的时候 赋值泛型 需要在方法中声明泛型.
--静态方法的泛型
public static<N> void sayHi(N n) { System.out.println(n); }
不能直接使用类声明的泛型 ,直接使用类型调用静态方法时,没有对象的创建, Z泛型还没有被赋值.
使用泛型时,可以单独声明一下 如上的例子加在修饰符后.另外接口也可以使用泛型
// 泛型接口 interface InterA<M>{ public abstract void fun(M m); } //实现类 class InterAImpl implements InterA<String>{ @Override public void fun(String m) { // TODO Auto-generated method stub }
---泛型遍历集合
--好处2可以避免向下强转类型的麻烦
public static void fun() { // 泛型 前后要保持一致 //JDK 1.7 菱形泛型 : 可省略后面的泛型 ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("a"); arrayList.add("b"); arrayList.add("c"); arrayList.add("d"); //遍历集合 ListIterator<String> listIterator = arrayList.listIterator(); //正向遍历 while (listIterator.hasNext()) { //获取集合中的元素 String string = (String) listIterator.next(); System.out.println(string); } System.out.println("<------------------------->"); //逆向遍历时 要先正向遍历将迭代器指针移到集合最下方 while (listIterator.hasPrevious()) {//判断前一个元素是否存在 //获取前一个元素 String string = (String) listIterator.previous(); System.out.println(string); } }--好处3 将运行时的错误转到编译时报错
public static void fun2() { //不加泛型保存3个学生 ArrayList<Student> list = new ArrayList<>(); list.add(new Student("空", 20)); list.add(new Student("凸", 15)); list.add(new Student("海", 14)); //从集合中取出一个元素 Object object = list.get(0); Student student = (Student)object; System.out.println(student.getName()); // 从集合中 取出一个元素 强转工人类型 //调用工人的工作方法 //元素类型你可以 随意强转 没有约束 //编译时不报错 // 加上泛型 可以在编译的时候 有错误提示 让集合保存的元素 更加安全. // Worker worker = (Worker) list.get(1); // worker.work(); }
二 多参数的参数
public static void fun4() { //数组转集合 int [] array = {1,2,3,4,5}; //根据泛型 这个集合中每一个元素都是数组 List<int[]> list = Arrays.asList(array); System.out.println(list); //直接传入int数组 系统不会帮你 自动装箱 //直接把数组中元素放入集合中. Integer [] newArray = {1,2,3,4,5}; List<Integer> asList = Arrays.asList(newArray); System.out.println(asList); }
public static void fun5() { // 调用多参数数组 int [] array= {1,3,2,5}; fun4(2,array);//方式一 // fun4(0,8,7,2,6,2);//方式二 }
// int ...num 这个参数可以看成一个数组 //可以当做数组遍历 使用方式 //1. 直接传入一个数组 //2.可以传多个数用逗号分开 //注意: 同类型多参数时 最好把多参数放到最后 public static void fun4(int a,int ...num ) { for (int i = 0; i < num.length; i++) { System.out.println(num[i]); } System.out.println(a); }
三 泛型 <? extends E>
addAll 就是利用这个类型
?是子类 E是父类 ,只能使用父类的子类 或者本类.也叫向下限定
public static void fun1() { // addAll(Collection<Student extends Person> c) //创建一个person 集合 ArrayList<Person> list1 = new ArrayList<>(); list1.add(new Person("wang1",11)); list1.add(new Person("wang2",11)); //创建一个student集合 保存两个student ArrayList<Student> list2 = new ArrayList<>(); list2.add(new Student("heh", 10)); list2.add(new Student("hew", 10)); list1.addAll(list2); System.out.println(list1); // list2.addAll(list1); }上面的例子中student 是 person 类的子类 ,所以
list1.addAll(list2); 是OK的
list2.addAll(list1); 是错误的.
删除循环
public static void fun2() { //循环删除 //创建一个元素保存 a b c d //删除b (使用循环) ArrayList<String> List = new ArrayList<>(); List.add("a");//0 List.add("b");//1 List.add("b");//2 List.add("c");//3 List.add("d");//4 for (int i = 0; i < List.size(); i++) { if (List.get(i).equals("b")) { //是 b 就删了 // 删除后 要退回角标 List.remove(i--); } } System.out.println(List); }
List.remove(i);
a b c d
List.remove(i--);
a c d
在循环时, 集合长度变化,当索引值为1的"b" 被删除后 索引为2的"b" 的索引则变成1 i++之后,第二的b就无法被删除了.
另外使用迭代器也能避免这种问题
public static void fun3() { //迭代器删除 ArrayList<String> List = new ArrayList<>(); List.add("a");//0 List.add("b");//1 List.add("b");//2 List.add("c");//3 List.add("d");//4 ListIterator<String> listIterator = List.listIterator(); while (listIterator.hasNext()) { String string = (String) listIterator.next(); if (string.equals("b")) { listIterator.remove(); //迭代器中需要使用 //迭代器类中的删除方法 //避免出现并发修改异常 } } System.out.println(List); }