集合、迭代器、加強for循環、泛型

1集合java

集合是java中提供的一種容器,能夠用來存儲多個數據。數組

數組的長度是固定的。集合的長度是可變的。集合中存儲的元素必須是引用類型數據。this

 

1.1ArrayList集合存儲元素(複習)spa

例:3d

public class Person {
	private String name;
	private int age;
	public Person() {
		super();
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = 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;
	}	
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}	
}

 

import java.util.ArrayList;
public class Test1 {
	public static void main(String[] args) {
		//集合複習:存儲基本數據類型
		ArrayList<Double> arr1=new ArrayList<Double>();
		arr1.add(1.6);
		arr1.add(2.3);
		arr1.add(3.6);
		
		for(int i=0;i<arr1.size();i++){
			System.out.print(arr1.get(i)+" ");
		}
		
		System.out.println();
		
		//集合存儲引用數據類型
		ArrayList<Person> arr2=new ArrayList<Person>();
		arr2.add(new Person("張三",18));//存匿名對象
		arr2.add(new Person("小紅帽",8));
		arr2.add(new Person("大灰狼",55));
		
		for(int i=0;i<arr2.size();i++){
			System.out.println(arr2.get(i)); //調用toString方法,已重寫
		}
	}
}

 

1.2集合的繼承實現關係指針

經常使用的:code

 

1.3 Collection接口對象

 

Collection接口是集合中的頂層接口,它中定義的全部功能子類均可以使用。blog

Collection 是層次結構中的根接口。Collection 表示一組對象,這些對象也稱爲 collection 的元素。一些 collection 容許有重複的元素,而另外一些則不容許。一些 collection 是有序的,而另外一些則是無序的。排序

(這裏的有序不是指元素在值上的排序,而是指存、取的順序一致,怎麼存就怎麼取,有索引下標)

 

1.3.1 Collection經常使用方法

Collection是接口,因此全是抽象方法。

須要用多態new對象。

例:

import java.util.Collection;
import java.util.ArrayList;

public class CollectionTest {
	public static void main(String[] args) {
		//建立對象
		Collection<String> col=new ArrayList<String>();
		
		//添加元素
		col.add("中國");
		col.add("你好");
		col.add("java");
		
		//判斷集合中是否包含某元素
		boolean flag=col.contains("java");	
		if(flag){
			System.out.println("true,包含元素");
		}		
		
		//移除元素
		boolean dels=col.remove("你好"); //這個是返回布爾值
		if(dels){
			System.out.println("移除成功");
		}		
		
		//向下轉型
		ArrayList<String> arr=null; //定義成全局,否則遍歷時取不到
		if(col instanceof ArrayList){
			arr=(ArrayList<String>)col;
		}
		
		System.out.println();
		
		//遍歷		
		System.out.println("遍歷結果:");
		for(int i=0;i<arr.size();i++){
			System.out.print(arr.get(i)+" ");			
		}
		
		System.out.println();
		System.out.println();
		
		//轉成數組
		Object[] strs=col.toArray();		
		System.out.println("遍歷數組:");
		for(int i=0;i<strs.length;i++){
			//String str=(String)strs[i];//這裏是Object型數組,若是想轉成String數組,不能直接強轉,要給元素轉型
			System.out.print(strs[i]+" ");			
		}
		
		System.out.println();
		System.out.println();
		
		//清除內容
		col.clear();		
		System.out.println("清除後:");
		for(int i=0;i<arr.size();i++){
			System.out.print(arr.get(i)+" ");			
		}		
	}
}

注意:

1注意方法的返回值類型

2必定要指定泛型,否則還要強轉

例:會有警告

 

 

1.4 Iterator迭代器

1.4.1定義

java中提供了不少個集合,它們在存儲元素時,採用的存儲方式不一樣。

List有序(有下標索引),set無序(看上面的繼承體系圖)

要取出這些集合中的元素,可經過一種通用的獲取方式來完成。

 

迭代定義:

Collection集合元素的通用獲取方式:在取元素以前先要判斷集合中有沒有元素,若是有,就把這個元素取出來,繼續判斷,若是還有就再取出出來。一直把集合中的全部元素所有取出。這種取出方式專業術語稱爲迭代。

 

集合中把這種取元素的方式描述在Iterator接口中。

 

1.4.2 Iterator接口的經常使用方法

 

 

hasNext()方法:用來判斷集合中是否有下一個元素能夠迭代。若是返回true,說明能夠迭代。

next()方法:用來返回迭代的下一個元素,並把指針向後移動一位。

 

1.4.3 Iterator接口的對象

 

Iterable對象裏有一個iterator() 方法,能夠返回Iterator對象,Collection繼承了這個方法,那麼其子類或實現類就都有了這個方法,能夠用這個方法建立Iterator對象。

 

 

例:(Iterator接口也可使用<>來控制迭代元素的類型的

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class IteratorTest {
	public static void main(String[] args) {
		Collection<Integer> col=new ArrayList<Integer>();
		col.add(1);
		col.add(2);
		col.add(3);
		col.add(4);
		
		//獲取迭代器對象	
		Iterator<Integer> it=col.iterator();
		
		//循環
		while(it.hasNext()){
			int i=it.next(); //自動拆箱
			System.out.println(i);
		}		
	}
}

 

注意:

1next()只能用一次,再調用,指針還會日後走,想判斷,要先把值獲取到,再判斷值。

例:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class I2 {
	public static void main(String[] args) {
		Collection<Integer> col=new ArrayList<Integer>();
		col.add(1);
		col.add(2);
		col.add(3);
		col.add(4);
		
		//獲取迭代器對象	
		Iterator<Integer> it=col.iterator();		
		
		//用循環
		while(it.hasNext()){
			if(it.next()==2){
				System.out.println(it.next());
			}
		}		
	}
}

說明next()又向後走了,因此要改爲這樣:

while(it.hasNext()){
int i=it.next();
	if(i==2){
		System.out.println(i);
	}			
}

 

還能夠for循環,但不經常使用

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class I2 {
	public static void main(String[] args) {
		Collection<Integer> col=new ArrayList<Integer>();
		col.add(1);
		col.add(2);
		col.add(3);
		col.add(4);
		
		for(Iterator<Integer> it=col.iterator();it.hasNext();){
			System.out.println(it.next());
		}		
	}
}

 

2)在進行集合元素取出時,若是集合中已經沒有元素了,還繼續使用迭代器的next方法,將會發生java.util.NoSuchElementException沒有集合元素的錯誤。

例:

 

 

1.5集合元素的向下轉型

集合中能夠存儲任何對象,那麼存放進去的數據就再也不是原來類型了,而是提高成了Object

若是集合中存放的是多個對象,這時進行向下轉型會發生類型轉換異常。

 

 

3加強for循環

加強for循環是JDK1.5之後出來的一個高級for循環,專門用來遍歷數組和集合的。它的內部原理實際上是個Iterator迭代器,因此在遍歷的過程當中,不能對集合中的元素進行增刪操做。

 

3.1格式:

for(元素的數據類型 變量 : Collection集合or數組){

}

例:

import java.util.ArrayList;
import java.util.Collection;

public class forTest {
	public static void main(String[] args) {
		Collection<String> col=new ArrayList<String>();
		col.add("你好");
		col.add("快樂");		
		
		//使用加強for
		for(String str:col){
			System.out.println(str); //取到的就是String對象
		}
		
		//使用加強for遍歷數組
		int[] arr={1,2,3,4,5};
		for(int i:arr){
			System.out.print(i+" "); //i就是每一個值
		}
	}
}

 

3.2對比:

1迭代器只能迭代集合,加強for能遍歷集合和數組。

2for循環必須有被遍歷的目標。目標只能是Collection或者是數組。只用來遍歷,不進行任何操做。

遍歷數組時,若是僅爲遍歷,可使用加強for。

若是要對數組的元素進行操做,使用老式for循環,(由於能夠經過標操做

 

3.3總結:

遍歷集合:三種方式

遍歷數組:兩種方式

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Test1 {
	public static void main(String[] args) {
		showList();
		showArr();
	}
	
	public static void showList(){
		Collection<String> col=new ArrayList<String>();
		col.add("abc");
		col.add("ABC");
		col.add("12345");
		
		//for循環遍歷
		System.out.println("for循環遍歷集合:");
		ArrayList<String> arr=null;
		if(col instanceof ArrayList){
			arr=(ArrayList<String>)col;
		}
		for(int i=0;i<arr.size();i++){
			System.out.print(arr.get(i)+"\t");
		}
		
		//迭代器
		System.out.println();
		System.out.println("迭代器集合:");
		Iterator<String> it=col.iterator();
		while(it.hasNext()){
			System.out.print(it.next()+"\t");
		}
		
		//加強for
		System.out.println();
		System.out.println("加強for遍歷集合:");
		for(String str:col){
			System.out.print(str+"\t");
		}
	}
	
	public static void showArr(){
		System.out.println();
		int[] arr={1,2,3,4,5};
		
		System.out.println("普通for遍歷數組:");
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+" ");
		}
		
		System.out.println();
		System.out.println("加強for遍歷數組:");
		for(int i:arr){
			System.out.print(i+" ");
		}		
	}
}

 

4泛型

前面一些例子,集合中是能夠存聽任意對象的提高成Object類型,這時容易發生

ClassCastException類型轉換異常,泛型就是爲了解決這個問題。

 

4.1定義

使用集合時,必須明確集合中元素的類型這種方式稱爲泛型。

泛型,用來靈活地將數據類型應用到不一樣的類、方法、接口當中。將數據類型做爲參數進行傳遞。

 

定義格式:

修飾符 class 類名<表明泛型的變量> { }

修飾符 interface接口名<表明泛型的變量> { }

 

E就是一個變量,是element的意思,在何時明確:

1)實現或繼承時明確

Public class MyList<String> implements list<E>{}

Public class MyList<E> implements list<String>{}

2new對象時明確

Api中帶<E>的方法都是如此

 

4.2使用泛型的好處

將運行時期的ClassCastException,轉移到了編譯時期變成了編譯失敗。避免了類型強轉的麻煩。

Tips:

泛型:又叫僞泛型,編譯時不進.class文件   (註釋也不進)

只在java代碼中對集合存儲數據類型進行約束

 

4.3泛型通配符

定義方法時,沒法肯定具體集合中的元素類型是什麼,可使用泛型通配符<?>,用來佔空。

例:

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

public class Test02 {
	public static void main(String[] args) {
		ArrayList<String> arr=new ArrayList<String>();
		arr.add("中國");
		arr.add("java");
		
		HashSet<Integer> set=new HashSet<Integer>();
		set.add(1);
		set.add(2);
		
		showAll(arr);
		showAll(set);
	}
	
	//泛型通配符
	public static void showAll(Collection<?> col){
		Iterator<?> it=col.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
	}
}

可是一旦使用泛型的通配符後,只能使用Object類中的共性方法,集合中元素自身方法沒法使用。(能夠向下轉型,可是太麻煩了)

 

4.4泛型限定

泛型裏面沒有向上向下轉型的概念。因此要定好。

限定泛型的上限:

格式:? extends E

? 表明接收E類型或者E的子類型的元素

 

限定泛型的下限:

格式:? super E

? 表明接收E類型或者E的父類型的元素(父類型,不僅是父類)

 

例:

//員工類
public abstract class Emp {
	public abstract void work();
}

 

//經理類
public class Manager extends Emp{	
	public void work() {
		System.out.println("經理管理");		
	}
}

 

//服務員類
public class Waiter extends Emp{	
	public void work() {
		System.out.println("服務員上菜");		
	}
}

 

//廚師類
public class Cooker extends Emp{	
	public void work() {
		System.out.println("廚師炒菜");		
	}
}

  

import java.util.ArrayList;

public class Test03 {
	//四個類:員工,經理,服務員,廚師 都有work方法
	//傳入三個類調用其work方法	
	public static void main(String[] args) {		
		Manager m=new Manager();
		ArrayList<Manager> arr1=new ArrayList<Manager>();
		arr1.add(m);
		
		Waiter w=new Waiter();
		ArrayList<Waiter> arr2=new ArrayList<Waiter>();
		arr2.add(w);
		
		Cooker c=new Cooker();
		ArrayList<Cooker> arr3=new ArrayList<Cooker>();
		arr3.add(c);
		
		working(arr1); 
		working(arr2);
		working(arr3);
		
		ArrayList<Object> arr4=new ArrayList<Object>();
		arr4.add("這是一個Object類型的數據");
		arr4.add("這是一個Object類型的數據2");
		working2(arr4);
		
	}
	public static void working(ArrayList<? extends Emp> arr){ //限定泛型的上限
		Emp emp=arr.get(0);
		emp.work();
	}
	
	public static void working2(ArrayList<? super Emp> arr){ //限定泛型的下限
		for(int i=0;i<arr.size();i++){
			System.out.println(arr.get(i));
		}
	}	
}

這裏若是是接口,也能夠用extends。

相關文章
相關標籤/搜索