ArrayList集合存储元素
package com.oracle.demo01; public class Person { private String name; private int age; public Person(String name, int age) { super(); //有参构造 this.name = name; this.age = age; }//无参构造 public Person() { super(); } //get set 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; } //toString方法 public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } } ------------------------------------------------------------- import java.util.ArrayList; public class Demo01 { public static void main(String[] args) { /*ArrayList存基本数据类型 ArrayList<Integer> arr=new ArrayList<Integer>(); arr.add(1);//相当于 自动装箱(new Integer) arr.add(0);*/ //自定义数据类型 ArrayList<Person> arr=new ArrayList<Person>(); arr.add(new Person("小红帽",25)); arr.add(new Person("大灰狼",24)); arr.add(new Person("袁一鸣",21)); //遍历 for(int i=0;i<arr.size();i++){ System.out.println(arr.get(i));//get (i)取对象 } } }
集合继承的实现关系
Collention接口:所有集合中顶层接口,是所有父类的接口
基本方法:所有集合共性的方法
import java.util.ArrayList; import java.util.Collection; public class Demo02 { public static void main(String[] args) { //接口类型指向子类对象 Collection<Integer> col=new ArrayList<Integer>(); col.add(10); col.add(20); //清空集合 //col.clear(); //clear清空的是内容 //判断集合中是否包含该元素 用contains boolean flag=col.contains(20); System.out.println(flag); //根据值删除集合中的元素 用remove方法 col.remove(10); //遍历 向下转型 if(col instanceof ArrayList){ ArrayList<Integer> arr=(ArrayList<Integer>)col; for(int i=0;i<arr.size();i++){ System.out.println(arr.get(i)); } } //将集合转为数组 Object[] obj=col.toArray(); //遍历 for(int i=0;i<obj.length;i++){ System.out.println(obj[i]); } } }
创建集合的格式
方式1:Collection<元素类型> 变量名 = new ArrayList<元素类型>();
方式2:Collection 变量名 = new ArrayList();
写集合如果不加泛型 容器就会没有规定 装什么都可以
package com.oracle.demo01; //测试 不加泛型时 提升为Object类型 import java.util.ArrayList; import java.util.Collection; public class Demo03 { public static void main(String[] args) { //一个接口 一个子类对象 没+泛型 会显示黄线 Collection col=new ArrayList(); //当不写范型时,类型是object类型,默认向上转型,遍历时 //当不加泛型 数据类型就是Object 容器放什么都可以,没有规定 col.add(123); col.add("123"); col.add(12.3); //向下转型 if(col instanceof ArrayList){ //如果是转成 ArrayList ArrayList arr=(ArrayList) col; //for循环 for(int i=0;i<arr.size();i++){ System.out.println(arr.get(i));//获取i为Object类型 } //以后写集合一定要加 泛型,否则会很啰嗦 } } }
Iterator迭代器
Collection集合元素的通用获取方式:在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代
用方法判断容器有没有元素 ,如果有,取出,在判断,一直到取完为止
集合中把取元素的方式描述在 Iterator接口里
两个方法
hasNext返回值是boolean 所以是用来判断的,如果扔有元素可以取 返回 true
next 返回值 E 可理解为 Object 或 泛型,泛型写什么 就返回什么,取值用的
Iterator的next()方法返回值类型:Object
pm
集合元素向下转型
package com.oracle.demo01; //向下转型 import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class Demo05 { public static void main(String[] args) { Collection col=new ArrayList(); col.add("abc"); col.add("bcd"); col.add("efg"); //获取迭代器对象 Iterator it=col.iterator(); while(it.hasNext()){ //获取每个元素 Object s=it.next(); //判断元素是否是String类型 if(s instanceof String){ //向下转型 String str=(String)s; //调用子类独有的方法 System.out.println(str.length()); } } } }
迭代器只能遍历集合
增强for
1.5之后,专门遍历数组和集合,原理就是Iterator迭代器,遍历过程中,不能对集合的元素进行增删
格式:
for <元素数据类型> 变量 :collection集合or数组(){ }:无下标概念,按顺序一个一个取值。用于遍历集合collection和数组,不能在遍历过程中对集合元素增删操作
package com.oracle.demo01; //增强for import java.util.ArrayList; import java.util.Collection; public class Demo06 { public static void main(String[] args) { /*for(你容器中存放的数据类型 变量名:你要遍历的容器的名字){ System.out.println(变量名); }*/ //创建一个多态对象 Collection<String> col=new ArrayList<String>(); col.add("abc"); col.add("bcd"); col.add("efg"); //s就是循环遍历的对象 for(String s:col){ System.out.println(s); //打印字符串长度 System.out.println(s.length()); } } } ------------------------------------------------ package com.oracle.demo01; //用增强for自定义类型 import java.util.ArrayList; import java.util.Collection; public class Demo07 { public static void main(String[] args) { Collection<Person> col=new ArrayList<Person>(); col.add(new Person("哆啦A梦",88)); col.add(new Person("静静",89)); //增强for循环遍历 for(Person p:col){ //打印获取 System.out.println(p.getName()+"..."+p.getAge()); } } } -------------------------------------------------- package com.oracle.demo01; //增强for遍历数组 public class Demo08 { public static void main(String[] args) { String[] arr={"a","b","c","d"}; for(String s:arr){ System.out.println(s); } } }
增强for和老式for区别
都是遍历取值用的
增强for:只能遍历集合collection和数组
建议:如果只对数组遍历,用增强for,如果对数组的元素操作,也就是操作下标 得用 老式for
泛型
集合中可以放任意对象,把对象存储集合后,会提升为Object类型,取出每一个对象时,要采用类型转换
如果向下转换不加判断,容易产生 java.lang.ClassCastException(类型转换异常 ),解决这种问题就必要明确集合中元素的类型,这种方式叫泛型
含有泛型的类
定义格式:修饰符 class 类名<代表泛型的变量> { }
class ArrayList<E>{ public boolean add(E e){ } public E get(int index){ } }
<E> 创建对象时,确定泛型的类型,当定义泛型后,下面使用的方法里的参数都会自动生成泛型的数据类型,ArrayList<String> list = new ArrayList<String>();
含有泛型的接口
就是在接口名后面加泛型 格式:修饰符 interface 接口名 <代表泛型的变量> { }
public interface Iterator<E> { //定义了泛型 E public abstract E next(); //抽象方法都是 E }
总结:
含有泛型的类 new对象时 明确
含有泛型接口
1.实现类不明确,new对象时明确
ArrayList<String> list = new ArrayList<String>();
Iterator<String> it = list.iterator();
2. 实现接口时明确
1.public class AAA<E> implements Iterator<E>{ } AAA<String> a=new AAA<String>();
2.public final class Scanner implements Iterator<String> {
public String next(){ }
}
泛型好处
将运行时期的ClassCastException,转移到编译时期变成了编译失败,避免强转麻烦。
泛型通配符 “?”
泛型限定
限定泛型的上限:
格式:? extends E? 代表接收E类型或者E的子类型的元素 例,泛型限定为:? extends Person 则 ? 代表接收Person类型或者Person子类型的元素
限定泛型的下限:
格式:? super E ? 代表接收E类型或者E的父类型的元素 例,泛型限定为:? super Student 则 ? 代表接收Student类型或者Student父类型的元素
package com.oracle.demo01; //泛型通配符 import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; public class Demo10 { public static void main(String[] args) { //创建一个集合并确定String泛型 ArrayList<String> arr=new ArrayList<String>(); arr.add("a"); arr.add("b"); //创建一个集合确定Integer泛型 HashSet<Integer> set=new HashSet<Integer>(); set.add(123); set.add(456); //调 get(arr); get(set); } //写一个方法来遍历这两个集合 向上转型 public static void get(Collection<?> col){ //获取迭代器对象 Iterator<?> it=col.iterator(); //判断集合中是否有元素 while(it.hasNext()){ //取元素 System.out.println(it.next()); } } }
set怎么存未必按顺序取
举例:
package com.oracle.demo01; //创建员工类定义为抽象类 public abstract class Emp { //抽象方法 public abstract void work(); } ------------------------------------------- package com.oracle.demo01; //厨师类 继承员工类 public class Cooker extends Emp{ //重写员工类的方法 public void work(){ System.out.println("厨师炒菜"); } } ------------------------------------------ package com.oracle.demo01; //创建服务员类 继承员工类 public class Waiter extends Emp{ //重写 public void work(){ System.out.println("服务员端菜"); } } ------------------------------------------ package com.oracle.demo01; import java.util.ArrayList; import java.util.Iterator; public class Demo { public static void main(String[] args) { //创建一个cooker集合 ArrayList<Cooker> arr1=new ArrayList<Cooker>(); //给cooker传参 arr1.add(new Cooker()); arr1.add(new Cooker()); //创建一个服务员类集合 ArrayList<Waiter> arr2=new ArrayList<Waiter>(); //给waiter传参 arr2.add(new Waiter()); arr2.add(new Waiter()); get(arr1); get(arr2); } //写一个方法来遍历容器 泛型限定:让子类通配符?继承Emp员工类 public static void get(ArrayList<? extends Emp> arr){ //获得iterator对象 Iterator<? extends Emp> it=arr.iterator(); //<?> 就是Object类型 while(it.hasNext()){ it.next().work(); } } }
总结通配符:
当一个方法里有两个集合,不同的泛型,这时可以写一个方法遍历两个容器