一泛型
泛型: 标识着集合中保存的元素是什么类型.
泛型的好处:
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);
}