您好,欢迎访问一九零五行业门户网

Java集合框架体系结构介绍

一、集合概述
1)集合的概念现实生活中的集合:很多事物凑在一起。
数学中的集合:具有共同属性的事物的总体。
java中的集合类:是一种工具类,就像是容器,储存任意数量的具有共同属性的对象。
2)集合的作用如果一个类的内部有多相同类型的属性,并且它们的作用和意义是一样的。比如说,一个学生可以选多个课程,对于一个学生类来说,xx课程就是他的一个属性,而xx课程通常不只有一个。对于像这种情况,如果把每一个课程都定一个属性就太繁琐了,这里我们就要用到集合的概念。
综上所述,集合的作用有以下几点:
在类的内部,对数据进行组织。
简单而快速的搜索大数量的条目。
有的集合接口,提供了一系列排列有序的元素,并且可以在序列中间快速的插入或者删除有关元素。
有的集合接口,提供了映射关系,可以通过关键字(key)去快速查找到对应的唯一对象,而这个关键字可以是任意类型。
3)集合和数组的对比可以看出集合和数组的功能类似,都是把一系列的数据放入到一个容器中,但是在类的内部我们为什么要用集合而不是数组呢?
数组的长度固定,集合长度可变。集合的优势就在于,集合的长度是随着里面的内容而扩充的,而数组的长度是已经定义好的。
数组只能通过下标访问元素,类型固定(数组下标只能是整形的),而有的集合可以通过任意类型查找所映射的具体对象(key关键字可以是任意类型)。
二、java集合框架体系结构我们来简单看一下java集合框架:(还有很多接口和类没有列出,这里只列出常用的接口和类)
如图所示,java集合框架体系结构:collection与map是两个根接口。
collection接口:内部存储的是一个个独立的对象。包含:
1、list接口:序列,存储元素排列有序且可重复。实现类:arraylist,数组序列;实现类:linkedlist,链表。
2、queue接口:队列,存储元素排列有序且可重复。实现类:linkedlist,链表。
3、set接口:集,存储元素无序且不可重复。实现类:hashset,哈希集。
map接口:内部以<key,value>(任意类型)的一个映射去存储数据,这一个映射就是entry类(map的内部类)的实例。包括:实现类:hashmap,哈希表。
collection接口是list、set、queue接口的父接口,collection接口定义了可用于操作list、set和queue的方法--增删改查。(具体的collection接口的方法可以通过查api,这里就不列举了。)
其中,arraylist、hashset和hashmap是使用最多的三个实现类,这里我们将逐个介绍这三个实现类。
在这篇文章中将先介绍arraylist的用法。
三、arraylist实现类
list接口及其实现类--arraylist
list可以精确的控制每个元素的插入位置,或删除某个位置元素;
list有add()插入方法和get()获取方法;
arraylist--数组序列,是list的一个重要实现类
arraylist底层是由数组实现的,这也是其名字的由来。
那么如何使用这些集合呢?我们来通过一个小例子,写一个小程序来更直观的学习集合的使用方法。(之后的文章的例子也是基于此的)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
程序功能——模拟学生选课功能
选择课程(往集合添加课程)
删除所选的某门课程(删除集合中的元素)
查看所选课程
修改所选课程
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
以下是该程序的代码片段,因为是用于测试来介绍集合的使用,所以请不要在意细节,代码会一步步改进的。
 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 }

运用了泛型的话,用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集合框架体系结构介绍的详细内容。
其它类似信息

推荐信息