首頁  >  文章  >  Java  >  Java集合框架體系結構介紹

Java集合框架體系結構介紹

零下一度
零下一度原創
2017-07-23 10:24:532569瀏覽

一、集合概述<br>

1)集合的概念

現實生活中的集合:很多事物都湊在一起。

數學中的集合:具有共同屬性的事物的總體。

Java中的集合類:是一種工具類,就像是容器,儲存任意數量的具有共同屬性的物件。

2)集合的作用

如果一個類別的內部有多相同類型的屬性,並且它們的作用和意義是一樣的。比如說,一個學生可以選多個課程,對一個學生類來說,XX課程就是他的一個屬性,而xx課程通常不只有一個。對於像這種情況,如果把每一個課程都定一個屬性就太繁瑣了,這裡我們就要用到集合的概念。

    

綜上所述,集合的功能有以下幾點:

  1. 在類的內部,對資料進行組織。

  2. 簡單又快速的搜尋大數量的條目。

  3. 有的集合接口,提供了一系列排列有序的元素,並且可以在序列中間快速的插入或刪除有關元素。

  4. 有的集合接口,提供了映射關係,可以透過關鍵字(key)去快速查找到對應的唯一對象,而這個關鍵字可以是任意型別。

3)集合和陣列的比較

可以看出集合和陣列的功能類似,都是把一系列的資料放入到一個容器中,但是在類別的內部我們為什麼要用集合而不是數組呢?

  1. 陣列的長度固定,集合長度可變。 集合的優勢就在於,集合的長度是隨著裡面的內容而擴充的,而陣列的長度是已經定義好的。

  2. 陣列只能透過下標存取元素,類型固定(陣列下標只能是整形的),而有的集合可以透過任意型別尋找所對應的具體物件(key關鍵字可以是任意型別)。


二、Java集合框架體系結構

我們來簡單看java集合框架:(還有很多介面和類別沒有列出,這裡只列出常用的介面與類別)

如圖所示,JAVA集合框架體系結構:Collection與Map是兩個根介面。

Collection介面:內部儲存的是一個獨立的物件。包含:

1、List介面:序列,儲存元素排列有序且可重複。實作類別:ArrayList,陣列序列;實作類別:LinkedList,鍊錶。

2、Queue介面:佇列,儲存元素排列有序且可重複。實作類別:LinkedList,鍊錶。

3、Set介面:,儲存元素無序且不可重複。實作類別:HashSet,哈希集。

Map介面:內部以(任意型別)的一個映射去儲存數據,這一個映射就是Entry類別(Map的內部類別)的實例。包括:實作類別:HashMap,哈希表。

Collection接口是List、Set、Queue接口的父接口,Collection接口定義了可用於操作List、Set和Queue的方法--增刪改查。 (具體的Collection介面的方法可以透過查API,這裡就不列舉了。)

其中,ArrayList、HashSet和HashMap是使用最多的三個實作類,這裡我們將逐一介紹這三個實現類。

在這篇文章中將先介紹ArrayList的用法。


三、ArrayList實作類別<br>

#List介面及其實作類別--ArrayList

#List可以精確的控制每個元素的插入位置,或刪除某個位置元素;

List有add()插入方法和get()取得方法;

ArrayList--陣列序列,是List的一個重要實作類別

ArrayList底層是由陣列實現的,這也是其名字的由來。

那麼要如何使用這些集合呢?我們來透過一個小例子,寫一個小程式來更直覺的學習集合的使用方法。 (之後的文章的範例也是基於此的)

>>>>>>>>>>>>>> ;>>>>>>>>>>>>>>>>>>>>>>>>> ;>>>

程式功能-模擬學生選課功能

  1. 選擇課程(將課程新增至集合)

  2. 刪除所選的某門課程(刪除集合中的元素)

  3. #查看所選課程

  4. 修改所選課程

>>>>>>>>>>>>>> ;>>>>>>>>>>>>>>>>>>>>>>>>> ;>>>

以下是程式的程式碼片段,因為是用來測試來介紹集合的使用,所以請不要在意細節,程式碼會一步步改進的。

 1)建立學生類別和課程類別

 1 /** 2  * 学生类 3  * @author hysum 4  * 5  */ 6 public class Student implements { 7     private String name;//学生姓名 8     private String id;//学生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)建立替代課程類別

 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是接口,所以在建構方法中不能直接實例化,而透過ArrayList()實例化! ! !

例:public List coursesToSelect = new ArrayList();

Set、Map都類似,不可以直接對他實例化,要藉助對應的實例化類如HashSet(),HashMap();

3)在備選課程中加入課程

(新增元素)List下總共有4個為List插入元素的方法:

1.add(element);

2.add(index,element);

3.addAll(Arrays.asList(物件陣列名稱));

#4.addAll(index,Arrays.asList(物件陣列名稱));

以下用程式碼範例:

 1 /* 2  * 添加备选课程 3  */ 4 public void AddCourse() { 5         Course cr1=new Course("1","数据结构");//创建课程对象 6     this.CoresesToSelect.add(cr1);//用add(element)添加  7         Course temp=(Course)this.CoresesToSelect.get(0);//用get方法取出,注意类型转换 8     System.out.println("添加了课程:"+temp.getId()+" "+temp.getName()); 9         10         Course cr2=new Course("2","C语言");//创建课程对象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", "数据结构"), new Course("2", "C语言"), new Course("3", "汇编语言"),2                 new Course("4", "离散数学") };3         this.CoresesToSelect.addAll(Arrays.asList(course));//用addAll(Arrays.asList(对象数组名))添加

#注意:

1.物件被存入集合都變成object類型了取出時需要類型強轉。 (之後會用泛型來解決這個問題

範例:Course temp = (Course)coursesToSelect.get(0);

# 2.加入list中的位置(index)介於[0,length]之間;0代表插到隊頭,length代表插到隊尾。

3.如果加到List中的長度大於他目前的長度,則系統會出現異常,即數組下表越界異常,如:

1 Course cr2=new Course("2","C语言");//创建课程对象2 this.CoresesToSelect.add(2,cr2);//用add方法添加,超出集合现有长度 temp=(Course)

4)備選課程取出列印

以下三種方法都是用來取出List中元素的方法:

 -----for循環- ----

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是一個介面,依賴集合存在的。

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){//遍历集合中的每一个元素,作为每一个Object变量2 Course cr=(Course) obj;3 System.out.println("课程:" + cr.id + ":" + cr.name);4 }

#5)備選課程修改

使用set(index,Object element)修改元素,index表示索引位置,element表示新物件。

1     /*2      * 修改备选课程3      */4     public void Modify(int index, Course c) {// 传入要修改的参数5         this.CoresesToSelect.set(index, c);6     }

6)刪除備選課程元素

List中有remove(index),remove(物件值)和removeAll(Arrays.asList(物件陣列名稱) )方法來刪除容器中元素的值(用法和add類似)。

Course是資訊課程類,有id和name屬性;courseToSelect是list的序列容器物件。

 1     /* 2      * 删除备选课程,跟添加方法类似 3      */ 4     public void Remove(int index) {// 通过索引位置删除 5         this.CoresesToSelect.remove(index); 6     } 7  8     public void Remove(Course c) {// 通过课程对象删除 9         this.CoresesToSelect.remove(c);10 11     }12 13     public void Remove(Course[] c) {// 通过集合对象删除14         this.CoresesToSelect.removeAll(Arrays.asList(c));15 16     }

注意:

1.remove(index);删除位置要大于0并且小于List(序列容器)的长度。如果要删除全部可以用for循环嵌套此方法。

2.remove(object);先要获得删除的值,用法是先定义一个信息变量通过get()来存放要删除的值,然后用remove(删除的对象值);

3.removeAll(Arrays.asList());要删除指定的多个位置 Arrays.asLIst(对象数组名);作用是把数组转换为集合。用法是先创建信息对象数组存放删除元素的值,然后再用removeAll(Arrays.asList(对象数组名))方法,删除集合数组的元素。


四、应用泛型管理课程

在上面的几个例子中,小伙伴是否发现对于集合的取出和遍历都要将Object对象进行强制转换后才能使用,每次这样做不仅增加了编程难度还使代码特别繁琐,这里我们可以利用泛型来帮助我们更加方便地使用java集合。

首先,我们要知道没有使用泛型的话集合中的元素,可以是任意类型的对象(对象的引用),如果把某个对象放入集合,则会忽略他的类型把他当做Object处理。

那么我们就在刚才的例子里往备选课程类里的CoresesToSelect的List集合添加一些奇怪的东西会发什么有趣的事呢?

1    /*2      * 往List中添加一些奇怪的东西3      */4      public void testType(){5      System.out.println("能否往List中添加一些奇怪的东西呢?");6      this.CoresesToSelect.add("我不是课程,我是字符串!");7      }

当调用取出课程方法取出该元素时,运行时出错:

这是因为取出该元素时String类型不能强制转换为Course类型,那有什么办法来避免集合中被添加不希望添加的类型呢?

泛型则是规定了某个集合只可以存放特定类型的对象,会在编译期间进行类型检查,可以直接指定类型获取的集合元素。

泛型:指规定了某个集合只能存放特定类型的对象。

语法:ArrayList<String> array=new ArrayList<String>();  //规定array中只能存放String类型的对象

那么,了解了泛型之后,上面的例子里都可以加上泛型了,修改如下(只列出修改的部分):(自行对比)

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循环的修改:

1 for (Course obj : CoresesToSelect) {        
2     System.out.println("添加了课程:" + obj.getId() + " " + obj.getName());4 }
<br>

运用了泛型的话,用foreach语句时 存储变量应该为泛型的类型。for(Course a:courseToSelect),不必再用Object取出再强转,因为已经规定容器里装的都是Course类型。

使用泛型要注意

1.泛型集合中,不能添加泛型规定的类型和其子类以外的对象,否则会报错!

2.泛型中可以添加规定的类型的子类型的对象。如:

1 public void testChild() {2         ChildCourse ccr = new ChildCourse();3         ccr.id = "3";4         ccr.name = "我是子类型的课程对象实例~~";5         courses.add(ccr);6 }

3.不能直接添加基本类型(int,float等)的对象,如果要添加,需要使用其包装类。如:

1 public void testBasicType() {2 List<Integer> list = new ArrayList<Integer>();3 list.add(1);4 System.out.println("基本类型必须使用包装类作为泛型!" + list.get(0));5 }

五、通过Set集合管理课程

Set集合和List一样是Collection接口的子接口。它的方法跟List类似,但有稍许不同,因为Set集合是无序且不重复的。

1)添加学生选课的课程

add方法跟ArrayList一样

 1 li.stu=new Student("1","小明"); 2         System.out.println("欢迎"+li.stu.getName()+"同学选择课程"); 3         for(int i=0;i<3;i++){//循环三次添加选课 4             System.out.println("请选第"+(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 中添加某个对象,无论添加多少次,最终只会保留一个该对象(的引用)。同时,保留的是第一次添加的那一个。Set集合是无序的不可重复的。

2)打印输出学生选的课程

1 //输出学生选的课程2         for(Course c:li.stu.getCourses()){3             System.out.println(c.getId()+" "+c.getName());4 5         }

注意:迴圈遍歷Set中的每一個元素只能用foreach或iterator,不能像List一樣用get()方法。 因為是無序的每次的輸出結果都有些差別。

>>>>>>>>>>>>>>>>>>>>>>>>>>> ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#總結:

1、Set沒有像List中set()方法一樣就修改,因為List是有順序的,可以指定位置,而Set是無序的,可以用迴圈遍歷方式修改。

2、查詢遍歷時,Set不能用get()方法去獲取,因為無序沒有指定索引ID,但可以使用foreach和iterator來遍歷,但是每次遍歷出來可能順序都不一樣,還是因為無序造成的。

3、Set中的size(),add(),addAll(),remove(),removeAll()與List類似。

4、Set還可以加入null(但只能加入一個null,因為不重複);

以上是Java集合框架體系結構介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:Spring框架第六篇之Spring與DAO下一篇:Spring框架第六篇之Spring與DAO

相關文章

看更多