浅入深出之Java集合框架(上)
Java中的集合框架(上)
由于Java中的集合框架的內(nèi)容比較多,在這里分為三個(gè)部分介紹Java的集合框架,內(nèi)容是從淺到深,如果已經(jīng)有java基礎(chǔ)的小伙伴可以直接跳到淺入深出之Java集合框架(下)。
目錄
淺入深出之Java集合框架(上)
淺入深出之Java集合框架(中)??
淺入深出之Java集合框架(下)
Java集合框架編程練習(xí)小程序——撲克牌小游戲
一、集合概述
1)集合的概念
現(xiàn)實(shí)生活中的集合:很多事物湊在一起。
數(shù)學(xué)中的集合:具有共同屬性的事物的總體。
Java中的集合類:是一種工具類,就像是容器,儲(chǔ)存任意數(shù)量的具有共同屬性的對(duì)象。
2)集合的作用
如果一個(gè)類的內(nèi)部有多相同類型的屬性,并且它們的作用和意義是一樣的。比如說(shuō),一個(gè)學(xué)生可以選多個(gè)課程,對(duì)于一個(gè)學(xué)生類來(lái)說(shuō),XX課程就是他的一個(gè)屬性,而xx課程通常不只有一個(gè)。對(duì)于像這種情況,如果把每一個(gè)課程都定一個(gè)屬性就太繁瑣了,這里我們就要用到集合的概念。
????
綜上所述,集合的作用有以下幾點(diǎn):
3)集合和數(shù)組的對(duì)比
可以看出集合和數(shù)組的功能類似,都是把一系列的數(shù)據(jù)放入到一個(gè)容器中,但是在類的內(nèi)部我們?yōu)槭裁匆眉隙皇菙?shù)組呢?
二、Java集合框架體系結(jié)構(gòu)
我們來(lái)簡(jiǎn)單看一下java集合框架:(還有很多接口和類沒(méi)有列出,這里只列出常用的接口和類)
如圖所示,JAVA集合框架體系結(jié)構(gòu):Collection與Map是兩個(gè)根接口。
Collection接口:內(nèi)部存儲(chǔ)的是一個(gè)個(gè)獨(dú)立的對(duì)象。包含:
1、List接口:序列,存儲(chǔ)元素排列有序且可重復(fù)。實(shí)現(xiàn)類:ArrayList,數(shù)組序列;實(shí)現(xiàn)類:LinkedList,鏈表。
2、Queue接口:隊(duì)列,存儲(chǔ)元素排列有序且可重復(fù)。實(shí)現(xiàn)類:LinkedList,鏈表。
3、Set接口:集,存儲(chǔ)元素無(wú)序且不可重復(fù)。實(shí)現(xiàn)類:HashSet,哈希集。
Map接口:內(nèi)部以<Key,Value>(任意類型)的一個(gè)映射去存儲(chǔ)數(shù)據(jù),這一個(gè)映射就是Entry類(Map的內(nèi)部類)的實(shí)例。包括:實(shí)現(xiàn)類:HashMap,哈希表。
Collection接口是List、Set、Queue接口的父接口,Collection接口定義了可用于操作List、Set和Queue的方法--增刪改查。(具體的Collection接口的方法可以通過(guò)查API,這里就不列舉了。)
其中,ArrayList、HashSet和HashMap是使用最多的三個(gè)實(shí)現(xiàn)類,這里我們將逐個(gè)介紹這三個(gè)實(shí)現(xiàn)類。
在這篇文章中將先介紹ArrayList的用法。
三、ArrayList實(shí)現(xiàn)類
List接口及其實(shí)現(xiàn)類--ArrayList
List可以精確的控制每個(gè)元素的插入位置,或刪除某個(gè)位置元素;
List有add()插入方法和get()獲取方法;
ArrayList--數(shù)組序列,是List的一個(gè)重要實(shí)現(xiàn)類
ArrayList底層是由數(shù)組實(shí)現(xiàn)的,這也是其名字的由來(lái)。
那么如何使用這些集合呢?我們來(lái)通過(guò)一個(gè)小例子,寫一個(gè)小程序來(lái)更直觀的學(xué)習(xí)集合的使用方法。(之后的文章的例子也是基于此的)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
程序功能——模擬學(xué)生選課功能
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
以下是該程序的代碼片段,因?yàn)槭怯糜跍y(cè)試來(lái)介紹集合的使用,所以請(qǐng)不要在意細(xì)節(jié),代碼會(huì)一步步改進(jìn)的。
?1)創(chuàng)建學(xué)生類和課程類
1 /** 2 * 學(xué)生類 3 * @author hysum 4 * 5 */ 6 public class Student implements { 7 private String name;//學(xué)生姓名 8 private String id;//學(xué)生id 9 private Set courses;//所選課程的set集合 10 11 public Student(){} 12 public Student(String id,String name){ 13 this.id=id; 14 this.name=name; 15 this.courses=new HashSet();//初始化集合 16 } 17 public String getName() { 18 return name; 19 } 20 public void setName(String name) { 21 this.name = name; 22 } 23 public String getId() { 24 return id; 25 } 26 public void setId(String id) { 27 this.id = id; 28 } 29 public Set getCourses() { 30 return courses; 31 } 32 public void setCourses(Set courses) { 33 this.courses = courses; 34 } 1 /** 2 * 課程類 3 * @author hysum 4 * 5 */ 6 public class Course { 7 private String id;//課程id 8 private String name;//課程名稱 9 10 public Course(){ 11 12 } 13 public Course(String name){ 14 this.name=name; 15 } 16 public String getId() { 17 return id; 18 } 19 public void setId(String id) { 20 this.id = id; 21 } 22 public String getName() { 23 return name; 24 } 25 public void setName(String name) { 26 this.name = name; 27 } 28 public Course(String id,String name){ 29 this.id=id; 30 this.name=name; 31 } 32 }2)創(chuàng)建備選課程類
1 /** 2 * 備選課程類 3 * 4 * @author hysum 5 * 6 */ 7 public class ListCourse { 8 private List CoresesToSelect;// 備選課程 9 private Student stu; 10 private static Scanner in; 11 { 12 in = new Scanner(System.in); 13 } 14 public ListCourse() { 15 this.CoresesToSelect = new ArrayList();// 初始化List集合 16 } 17 public List getCoresesToSelect() { 18 return CoresesToSelect; 19 } 20 21 public void setCoresesToSelect(List coresesToSelect) { 22 CoresesToSelect = coresesToSelect; 23 } 26 }注意:
List是接口,所以在構(gòu)造方法中不能直接實(shí)例化,而通過(guò)ArrayList()實(shí)例化!!!
例:public List coursesToSelect = new ArrayList();
Set、Map都類似,不可以直接對(duì)他實(shí)例化,要借助相應(yīng)的實(shí)例化類如HashSet(),HashMap();
3)在備選課程里添加課程
(添加元素)List下總共有4個(gè)為L(zhǎng)ist插入元素的方法 :
1.add(element);
2.add(index,element);
3.addAll(Arrays.asList(對(duì)象數(shù)組名));
4.addAll(index,Arrays.asList(對(duì)象數(shù)組名));
以下用代碼示例:
1 /* 2 * 添加備選課程 3 */ 4 public void AddCourse() { 5 Course cr1=new Course("1","數(shù)據(jù)結(jié)構(gòu)");//創(chuàng)建課程對(duì)象 6 this.CoresesToSelect.add(cr1);//用add(element)添加 7 Course temp=(Course)this.CoresesToSelect.get(0);//用get方法取出,注意類型轉(zhuǎn)換 8 System.out.println("添加了課程:"+temp.getId()+" "+temp.getName()); 9 10 Course cr2=new Course("2","C語(yǔ)言");//創(chuàng)建課程對(duì)象 11 this.CoresesToSelect.add(0,cr2);//用add(index,element)添加 12 temp=(Course)this.CoresesToSelect.get(0); 13 System.out.println("添加了課程:"+temp.getId()+" "+temp.getName()); 14 } 1 Course[] course = { new Course("1", "數(shù)據(jù)結(jié)構(gòu)"), new Course("2", "C語(yǔ)言"), new Course("3", "匯編語(yǔ)言"), 2 new Course("4", "離散數(shù)學(xué)") }; 3 this.CoresesToSelect.addAll(Arrays.asList(course));//用addAll(Arrays.asList(對(duì)象數(shù)組名))添加注意:
1.對(duì)象被存入集合都變成object類型了 取出時(shí)需要類型強(qiáng)轉(zhuǎn)。(之后會(huì)用泛型來(lái)解決這個(gè)問(wèn)題)
例:Course temp = (Course)coursesToSelect.get(0);
2.添加進(jìn)list中的位置(index)介于[0,length]之間;0代表插到隊(duì)頭,length代表插到隊(duì)尾。
3.如果添加到List中的長(zhǎng)度大于他目前的長(zhǎng)度,則系統(tǒng)會(huì)出現(xiàn)異常,即數(shù)組下表越界異常,如:
1 Course cr2=new Course("2","C語(yǔ)言");//創(chuàng)建課程對(duì)象 2 this.CoresesToSelect.add(2,cr2);//用add方法添加,超出集合現(xiàn)有長(zhǎng)度 temp=(Course)4)備選課程取出打印
以下三種方法都是用來(lái)取出List中元素的方法:
?-----for循環(huán)-----
1 public void testGet(){ 2 int size=CoursesToSelect.size(); 3 for(int i=0;i<size;i++){ 4 Course cr=(Course) CoursesToSelect.get(i); 5 System.out.println("取出的課程:"+cr.getId()+":"+cr.getName()); 6 } 7 }-----迭代器-----
Iterator是一個(gè)接口,依賴于集合存在的。
1 Iterator it=CourseToSelect.iterator(); 2 while(it.hasNext()){ 3 Course cr=(Course) it.next(); 4 System.out.println("課程:" + cr.id + ":" + cr.name); 5 }-----for each(推薦使用)-----
1 for(Object obj:CoursesToSelect){//遍歷集合中的每一個(gè)元素,作為每一個(gè)Object變量 2 Course cr=(Course) obj; 3 System.out.println("課程:" + cr.id + ":" + cr.name); 4 }5)備選課程修改
使用set(index,Object element)修改元素,index表示索引位置,element表示新對(duì)象。
1 /* 2 * 修改備選課程 3 */ 4 public void Modify(int index, Course c) {// 傳入要修改的參數(shù) 5 this.CoresesToSelect.set(index, c); 6 }6)刪除備選課程元素
List中有remove(index),remove(對(duì)象值)和removeAll(Arrays.asList(對(duì)象數(shù)組名))方法來(lái)刪除容器中元素的值(用法和add類似)。
Course是信息課程類,有id和name屬性;courseToSelect是list的序列容器對(duì)象。
1 /* 2 * 刪除備選課程,跟添加方法類似 3 */ 4 public void Remove(int index) {// 通過(guò)索引位置刪除 5 this.CoresesToSelect.remove(index); 6 } 7 8 public void Remove(Course c) {// 通過(guò)課程對(duì)象刪除 9 this.CoresesToSelect.remove(c); 10 11 } 12 13 public void Remove(Course[] c) {// 通過(guò)集合對(duì)象刪除 14 this.CoresesToSelect.removeAll(Arrays.asList(c)); 15 16 }注意:
1.remove(index);刪除位置要大于0并且小于List(序列容器)的長(zhǎng)度。如果要?jiǎng)h除全部可以用for循環(huán)嵌套此方法。
2.remove(object);先要獲得刪除的值,用法是先定義一個(gè)信息變量通過(guò)get()來(lái)存放要?jiǎng)h除的值,然后用remove(刪除的對(duì)象值);
3.removeAll(Arrays.asList());要?jiǎng)h除指定的多個(gè)位置? Arrays.asLIst(對(duì)象數(shù)組名);作用是把數(shù)組轉(zhuǎn)換為集合。用法是先創(chuàng)建信息對(duì)象數(shù)組存放刪除元素的值,然后再用removeAll(Arrays.asList(對(duì)象數(shù)組名))方法,刪除集合數(shù)組的元素。
四、應(yīng)用泛型管理課程
在上面的幾個(gè)例子中,小伙伴是否發(fā)現(xiàn)對(duì)于集合的取出和遍歷都要將Object對(duì)象進(jìn)行強(qiáng)制轉(zhuǎn)換后才能使用,每次這樣做不僅增加了編程難度還使代碼特別繁瑣,這里我們可以利用泛型來(lái)幫助我們更加方便地使用java集合。
首先,我們要知道沒(méi)有使用泛型的話,集合中的元素,可以是任意類型的對(duì)象(對(duì)象的引用),如果把某個(gè)對(duì)象放入集合,則會(huì)忽略他的類型把他當(dāng)做Object處理。
那么我們就在剛才的例子里往備選課程類里的CoresesToSelect的List集合添加一些奇怪的東西會(huì)發(fā)什么有趣的事呢?
1 /* 2 * 往List中添加一些奇怪的東西 3 */ 4 public void testType(){ 5 System.out.println("能否往List中添加一些奇怪的東西呢?"); 6 this.CoresesToSelect.add("我不是課程,我是字符串!"); 7 }當(dāng)調(diào)用取出課程方法取出該元素時(shí),運(yùn)行時(shí)出錯(cuò):
這是因?yàn)槿〕鲈撛貢r(shí)String類型不能強(qiáng)制轉(zhuǎn)換為Course類型,那有什么辦法來(lái)避免集合中被添加不希望添加的類型呢?
泛型則是規(guī)定了某個(gè)集合只可以存放特定類型的對(duì)象,會(huì)在編譯期間進(jìn)行類型檢查,可以直接指定類型獲取的集合元素。
泛型:指規(guī)定了某個(gè)集合只能存放特定類型的對(duì)象。
語(yǔ)法:ArrayList<String> array=new ArrayList<String>(); //規(guī)定array中只能存放String類型的對(duì)象那么,了解了泛型之后,上面的例子里都可以加上泛型了,修改如下(只列出修改的部分):(自行對(duì)比)
1 private Set<Course> courses;//所選課程的set集合 2 this.courses=new HashSet<Course>();//初始化集合 3 public Set<Course> getCourses() { 4 return courses; 5 } 6 public void setCourses(Set<Course> courses) { 7 this.courses = courses; 8 } 1 private List<Course> CoresesToSelect;// 備選課程 2 public ListCourse() { 3 this.CoresesToSelect = new ArrayList<Course>();// 初始化List集合 4 } 5 public List<Course> getCoresesToSelect() { 6 return CoresesToSelect; 7 } 8 9 public void setCoresesToSelect(List<Course> coresesToSelect) { 10 CoresesToSelect = coresesToSelect; 11 }foreach循環(huán)的修改:
1 for (Course obj : CoresesToSelect) { 2 System.out.println("添加了課程:" + obj.getId() + " " + obj.getName()); 4 }運(yùn)用了泛型的話,用foreach語(yǔ)句時(shí) 存儲(chǔ)變量應(yīng)該為泛型的類型。for(Course a:courseToSelect),不必再用Object取出再?gòu)?qiáng)轉(zhuǎn),因?yàn)橐呀?jīng)規(guī)定容器里裝的都是Course類型。
使用泛型要注意:
1.泛型集合中,不能添加泛型規(guī)定的類型和其子類以外的對(duì)象,否則會(huì)報(bào)錯(cuò)!
2.泛型中可以添加規(guī)定的類型的子類型的對(duì)象。如:
1 public void testChild() { 2 ChildCourse ccr = new ChildCourse(); 3 ccr.id = "3"; 4 ccr.name = "我是子類型的課程對(duì)象實(shí)例~~"; 5 courses.add(ccr); 6 }3.不能直接添加基本類型(int,float等)的對(duì)象,如果要添加,需要使用其包裝類。如:
1 public void testBasicType() { 2 List<Integer> list = new ArrayList<Integer>(); 3 list.add(1); 4 System.out.println("基本類型必須使用包裝類作為泛型!" + list.get(0)); 5 }五、通過(guò)Set集合管理課程
Set集合和List一樣是Collection接口的子接口。它的方法跟List類似,但有稍許不同,因?yàn)镾et集合是無(wú)序且不重復(fù)的。
1)添加學(xué)生選課的課程
add方法跟ArrayList一樣
1 li.stu=new Student("1","小明"); 2 System.out.println("歡迎"+li.stu.getName()+"同學(xué)選擇課程"); 3 for(int i=0;i<3;i++){//循環(huán)三次添加選課 4 System.out.println("請(qǐng)選第"+(i+1)+"門課程:"); 5 String Id=in.next(); 6 for(Course c:li.getCoresesToSelect()){ 7 if(c.getId().equals(Id)){ 8 li.stu.getCourses().add(c); 9 } 10 } 11 12 }注意:Set 中添加某個(gè)對(duì)象,無(wú)論添加多少次,最終只會(huì)保留一個(gè)該對(duì)象(的引用)。同時(shí),保留的是第一次添加的那一個(gè)。Set集合是無(wú)序的不可重復(fù)的。
2)打印輸出學(xué)生選的課程
1 //輸出學(xué)生選的課程 2 for(Course c:li.stu.getCourses()){ 3 System.out.println(c.getId()+" "+c.getName()); 4 5 }注意:循環(huán)遍歷Set中的每一個(gè)元素只能用foreach或iterator,不能像List一樣用get()方法。因?yàn)槭菬o(wú)序的每次的輸出結(jié)果都有些差別。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
總結(jié):
1、Set沒(méi)有像List中set()方法一樣就修改,因?yàn)長(zhǎng)ist是有序的,可以指定位置,而Set是無(wú)序的,可以用循環(huán)遍歷方式修改。
2、查詢遍歷時(shí),Set不能用get()方法去獲取,因?yàn)闊o(wú)序沒(méi)有指定索引ID,但可以使用foreach和iterator來(lái)遍歷,但是每次遍歷出來(lái)可能順序都不一樣,還是因?yàn)闊o(wú)序造成的。
3、Set中的size(),add(),addAll(),remove(),removeAll()與List類似。
4、Set還可以添加null(但只能添加一個(gè)null,因?yàn)椴恢貜?fù));
本篇主要講述了List和Set的基本操作:增刪改查,下一篇我將介紹Map接口的基本操作,有興趣的小伙伴可以加一下方的"關(guān)注"哦!
轉(zhuǎn)載于:https://www.cnblogs.com/hysum/p/7136480.html
總結(jié)
以上是生活随笔為你收集整理的浅入深出之Java集合框架(上)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: memcache调整value大小限制
- 下一篇: my batis的理解