前言——這篇文章是我初步瞭解泛型和List的遍歷方法 的記錄,例子來源於我網上的資料,但是代碼和註釋都是我自己重新寫了,這篇博文,好在代碼和代碼中的註釋,我將代碼的背景改了,高亮部分看起來很舒服,但是註釋部分就有一點偏暗,美中不足。
希望點開這篇博文後,不要輕易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 <>();
}
}
二.遍歷List的三種方法(以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
*/