前言——这篇文章是我初步了解泛型和容器的遍历方法 的记录,例子来源于我网上的资料,但是代码和注释都是我自己重新写了,这篇博文,好在代码和代码中的注释,我将代码的背景改了,高亮部分看起来很舒服,但是注释部分就有一点偏暗,美中不足。
希望点开这篇博文后,不要轻易pass,沉下心来,结合注释看懂每个Example,最重要的是自己写一遍,并且配上自己的注释,形成demo,方便日后查看。
目录
作为测试类的Hero类和Pet类(两个类的toString方法都重写了,便于输出)
作为测试类的Hero类和Pet类(两个类的toString方法都重写了,便于输出)
Hero类:
package Charactor;
import java.io.Serializable;
public class Hero {
public String name ;
public float hp;
public float damage;
public Hero() {
}
public Hero(String n, float h, float d) {
name = n;
hp = h;
damage = d;
}
public float getHp() {
return hp;
}
//重写Object方法是因为:
//输出容器中的对象时,调用的是toString()方法,重写后可以输出自定义内容。
public String toString(){
return name;
}
}
Pet类:
package code_180;
//用户自己定义的类,不允许修改
public class Pet {
public String type;
public String name;
public Pet(String type,String name) {
this.type = type;
this.name = name;
}
public String getType() {
System.out.println("In Pet");
return this.type;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
//重写toString,输出时可以输出姓名
public String toString() {
return name;
}
}
class Dog extends Pet{
public Dog(String name) {
super("Dog",name);
}
}
class Cat extends Pet{
public Cat(String name) {
super("Cat",name);
}
}
一.泛型Generic
1.不指定泛型的容器可以存放任意类型的对象
如下:容器中既可以存放Hero类对象,也可以存放Pet类对象
package code_180.Pet;
import java.util.ArrayList;
import java.util.List;
import Charactor.Hero;
public class TestGenericAndFor {
public static void main(String[] args) {
// TODO Auto-generated method stub
List container = new ArrayList();
//往容器中放入3个Hero对象
for(int i = 0 ;i < 3 ;i++) {
container.add(new Hero("hero"+ i, 1,1));
}
//往容器中放入3个Pet对象
for(int i = 3 ;i < 6 ;i++) {
container.add(new Pet("Pet","pet" +i));
}
System.out.println(container);
//记得0下标存储的对象是Hero对象,所以转化为Hero类型不会出错
Hero hero1 = (Hero)container.get(0);
//忘记了下标0存储的对象是Hero对象了,尝试将Hero类型转换成Pet类型,就会出现转型错误,会抛出异常
//特别是容器中存储的对象多了,程序员会忘了哪个位置存储什么类型
Pet pet1 = (Pet)container.get(0);
}
}
/*
运行结果:
[hero0, hero1, hero2, pet3, pet4, pet5]
Exception in thread "main" java.lang.ClassCastException: Charactor.Hero cannot be cast to code_180.Pet
at Test.TestGenericAndFor.main(TestGenericAndFor.java:36)
*/
2.指定泛型的容器只能存放指定类型的对象及其子类
package code_180;
import java.util.ArrayList;
import java.util.List;
import Charactor.Hero;
public class TestGenericAndFor {
public static void main(String[] args) {
// TODO Auto-generated method stub
TestGenericAndFor myTest = new TestGenericAndFor();
myTest.GenericTest();
}
public void GenericTest() {
//使用了泛型Generic,声明时就指定了容器中只能存放Pet类及其子类的对象
//存放其他类型的对象就会报错
List <Pet>container = new ArrayList<Pet>();
//往容器中存放3个Pet类型的对象
for(int i = 0 ; i < 3 ;i++) {
container.add(new Pet("Pet","Pet" + i));
}
//往容器中存放1个Dog类型的对象
container.add(new Dog("Dog"+3));
System.out.println(container);
//往容器中视图存放一个Hero类型的对象,会报错
//报错内容:The method add(Pet) in the type List<Pet> is not applicable for the
//arguments (Hero)
container.add(new Hero("hero4",1,1));
}
}
3.泛型的简写
我们已经知道了泛型的使用格式:
例如:List <Pet>container = new ArrayList<Pet>(); 前后都要有<Pet>。
但是也提供了一个略微减少代码量的使用格式:
例如: List <Pet>container = new ArrayList <>(); 这边前面需要<Pet>,后面简写为<>.
哈哈哈,是不是感觉多此一举,但是没办法,你可以不这么用,但是你必须得知道有这么一点!
package code_180;
import java.util.ArrayList;
import java.util.List;
import Charactor.Hero;
public class TestGenericAndFor {
public static void main(String[] args) {
// TODO Auto-generated method stub
TestGenericAndFor myTest = new TestGenericAndFor();
myTest.simpleGenericTest();
}
public void simpleGenericTest() {
//完整格式
List <Pet> container = new ArrayList <Pet>();
//简化格式
List<Pet> container1 = new ArrayList <>();
}
}
二.遍历容器的三种方法(以ArrayList为例 )
1.for循环搭配 size()获取容器的大小, get()返回指定位置的元素
package code_180;
import java.util.ArrayList;
import java.util.List;
import Charactor.Hero;
public class TestGenericAndFor {
public static void main(String[] args) {
// TODO Auto-generated method stub
TestGenericAndFor myTest = new TestGenericAndFor();
myTest.forTest();
}
public void forTest() {
List <Hero> heros = new ArrayList <>();
//装入3个Hero对象
for(int i = 0 ;i < 3 ;i++) {
heros.add(new Hero("hero" + i, 1,1));
}
//遍历3个Hero对象
for(int i = 0 ;i < heros.size(); i++) {
Hero temp = heros.get(i);
System.out.println(temp);
}
}
}
/*
运行结果:
hero0
hero1
hero2
*/
2.Iterator迭代器遍历
调用iterator()方法返回一个Iterator对象。注意,如果容器是泛型容器,返回的迭代器也将是对应的泛型迭代器
package code_180;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import Charactor.Hero;
public class TestGenericAndFor {
public static void main(String[] args) {
// TODO Auto-generated method stub
TestGenericAndFor myTest = new TestGenericAndFor();
myTest.iteratorTest();
}
public void iteratorTest() {
List <Hero> heros = new ArrayList<>();
//装入3个Hero对象
for(int i = 0 ;i < 3 ;i++) {
heros.add(new Hero("hero" + i, 1,1));
}
Iterator<Hero> it = heros.iterator();
//判断当前位置的下一个位置是否有元素,有的话返回true,没有的话返回false
while(it.hasNext()) {
Hero temp = (Hero)it.next();//"指针"移动到下一个元素的位置,并返回该元素
System.out.println(temp);
}
//迭代器遍历的for循环版本,这边记得要对it迭代器重新赋值,避免之前的影响
for(it= heros.iterator(); it.hasNext(); ) {
Hero temp = (Hero)it.next();
System.out.println(temp);
}
}
}
/*
运行结果:
hero0
hero1
hero2
hero0
hero1
hero2
*/
3.foreach遍历(增强型for遍历),其实内部实现代码还是用迭代器来实现的
package code_180;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import Charactor.Hero;
public class TestGenericAndFor {
public static void main(String[] args) {
// TODO Auto-generated method stub
TestGenericAndFor myTest = new TestGenericAndFor();
myTest.forEachTest();
}
public void forEachTest() {
//非泛型容器
List heros = new ArrayList();
//装入3个Hero对象
for(int i = 0 ;i < 3 ;i++) {
heros.add(new Hero("hero" + i, 1,1));
}
heros.add(new Pet("Pet","Pet3"));
for(Object temp: heros) {
System.out.println(temp);
}
}
}
/*
运行结果:
hero0
hero1
hero2
Pet3
*/