0130 泛型 list接口
1、泛型
如果不声明泛型,那么我们存储的所有东西都会自动生成Object类型的数据,这就是利用了多态
当创建一个ArrayList集合对象的时候声明泛型,则存储的所有数据都自动转型称为object类型
例:先不加泛型来举一个例子
public class Demo01 { public static void main(String[] args) { // TODO Auto-generated method stub ArrayList arr=new ArrayList(); arr.add("123"); arr.add(123); arr.add(1.2); for(Object d:arr){ System.out.println(d); } } }
当用增强for去遍历的时候因为不确定这个集合的类型,所以只能声明object类型,那我们遍历完成得到每一个,那这每一个不可以调用子类独有的方法,如果想调用只能将之歌类型向下转型,那么说这个集合里面存储了不只是一个类型的数据,所以向下转型有不确定性,就会出现类型转换异常。所以这就体现了泛型的重要性。
1.1泛型的定义
含有泛型的类,格式就是在类名后边加上泛型 修饰符 class 类名<代表泛型的变量> { } 那在什么时候明确这个泛型呢,两种方法,第一在创建这个类对象的时候明确泛型的类型,二在创建这个类的时候明确这个泛型的类型那么创建的所有的这个类对象就都是这个类型。
含有泛型的接口,格式 修饰符 interface接口名<代表泛型的变量> { } 明确泛型的两种方法,在实现这个接口的时候明确泛型,那么创建的所有对象都是这个泛型的类型,二创建这个接口的子类对象的时候明确泛型的类型。
泛型也是可以被继承的,如果父类加了泛型,那么继承他的子类必须加泛型。泛型没有多态,泛型不支持多态。
泛型通配符:
<?>
<? extends 父类>泛型的上线
<? super 子类>泛型的下线
根据这些个特点,我们来创建一下
(1)创建一个person类
public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } public Person(String name, int age) { super(); this.name = name; this.age = age; } public Person() { super(); } public void work(){ System.out.println("父类工作"); } }
创建一个student类继承person类
public class Student extends Person { public Student() { super(); // TODO Auto-generated constructor stub } public Student(String name, int age) { super(name, age); // TODO Auto-generated constructor stub } @Override public void work() { System.out.println("学生学习"); } }
创建一个测试类
public class Demo02 { public static void main(String[] args) { // TODO Auto-generated method stub ArrayList<Student> arr=new ArrayList<Student>(); Student s=new Student("小红",10); Student s1=new Student("小黑",11); arr.add(s); arr.add(s1); ArrayList<Person> brr=new ArrayList<Person>(); Person p1=new Person("小白",25); Person p2=new Person("小兰",26); brr.add(p1); brr.add(p2); get(arr); get(brr); ArrayList<String> crr=new ArrayList<String>(); crr.add("abc"); //get(crr); } //写一个通用的遍历方法 public static void get(ArrayList<? extends Person> arr){ //获取得带器对象 Iterator<?> it=arr.iterator(); while(it.hasNext()){ Person p=(Person)it.next(); p.work(); } } }
在测试类中我们创建了连个集合,一个是person一个是student,还创建了一个string类型的集合,要写一个通用方法去遍历这三个集合,首先这三个集合的泛型是不一样的,所以我们在写形参的时候就需要用通配符“?”去实现,就能成功遍历 person集合和student集合和string类型的集合,注意在写迭代器的时候也需要用通配符,因为要遍历三个不同类型的集合。遍历出来的元素相当于object类型,只能调用object类型中的方法,那么想调用自己类中独有的方法,那就需要向下转型,所以就可以调用work方法了。那么string类型的集合遍历出来的元素不能转为person类型,这就发生了类型转换异常,所以string不能调用这个get方法。
如果我将这个get方法形参改成<? extends Person >意思就是要么是person类型,要么就是person的子类类型才可以调用这个get方法
如果我将这个get方法的形参改成<? super Person>意思就是至少是person类型才可以调用这个方法(那以上方那个例子,就需要在创建对象的时候将泛型该更object类型,才可以)
2、list接口
特点:(1)可以存储重复元素(2)有序存储(3)有下标(索引)
常用方法:
(1)add(E e);添加元素
(2)add(int index,E e);指定位置添加元素
(3)get(int index);得到执行位置的元素
(4)remove(object obj);将obj移出集合
(4)remove(int index );将指定index位置的元素移出
(5)set(int index,E e);将指定index位置上的元素替换为e
代码展示:
public class Demo03 { public static void main(String[] args) { // TODO Auto-generated method stub List<String> list=new ArrayList<String>(); list.add("hello"); list.add(0,"你好"); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } //修改 list.set(0, "熊大"); //删除 list.remove(1); System.out.println("-----------"); for(String d:list){ System.out.println(d); } } }
list接口并发性异常:集合的长度是不可变得,也就是说我在遍历集合的时候不可以再添加元素
2-1:list集合纯输出数据结构
(1)堆栈:先进后出
(2)队列:先进先出
(3)数组:查找快,增删慢,数组长度不可变
(4)链表:查找慢,增删快,长度可变
2-2:list接口中的ArrayList集合;
2-3:list接口中的LinkedList集合:该集合风中了大量的堆头尾的元素的一些操作方法
常用方法:
(1)addFirst();在集合第一个位置添加元素
(2)addLast();在集合末尾位置添加元素
(3)getFist();得到集合第一位置的元素
(4)getLast();得到集合末尾位置的元素
(5)removeFirst();移出集合第一位置的元素
(6)removeLast();移出集合末尾位置的元素
(7)pop();推出集合中第一位置的元素
(8)push(E e);将e元素推入集合中
(9)isEmpty();判断集合是否为空
代码展示:
public class Demo04 { public static void main(String[] args) { // TODO Auto-generated method stub LinkedList<String> list=new LinkedList<String>(); list.addFirst("heiio"); list.add("你好"); list.addLast("熊二"); for(String s:list){ System.out.println(s); } //删除 list.removeFirst(); list.removeLast(); System.out.println(list.toString()); //kong System.out.println(!list.isEmpty()); } }
2-4 Vector集合
Vector集合已被ArrayList集合替代,所有方法和功能跟ArrayList集合一样,只不过就是方法名不一样