集合知识点.docx
- 文档编号:25050962
- 上传时间:2023-06-04
- 格式:DOCX
- 页数:16
- 大小:51.14KB
集合知识点.docx
《集合知识点.docx》由会员分享,可在线阅读,更多相关《集合知识点.docx(16页珍藏版)》请在冰豆网上搜索。
集合知识点
本章内容很重要,以后的学习以及工作中都会经常应用到。
重点是掌握用几个常用的集合接口和类来操纵集合里的数据。
至少需要掌握ArrayListTreeSetHashMap(HashTable)以及它们的特性,和对Swing组件的学习一样,要注意总结规律,总结添加元素,删除元素,获得元素(遍历)的通用方法和一些特殊的方法
1.什么是集合?
将多个对象合在一起变成一个统一的对象,然后通过这个统一的对象来实现对多个对象的管理(存储,检索,操作,传输数据)。
在数组里要进行这样的操作,可以会写很多算法,但在集合里,只需要调用其中的方法就可以了。
集合也可以对其中的元素进行操纵,增加、删除、更改。
同时,我们可以把存储之后的数据用于传输。
这体现了JAVA里的封装思想。
我们利用集合的功能特点,把我们对底层数据的操作封装起来,这样可以让程序的主要精力放在业务处理上,而不是对底层数据的操作上。
为什么要用集合?
数组不能动态改变长度,操作不方便
什么是集合框架?
JavaCollectionFramework(JCF)
–提供用于管理对象集合的接口和类
–包括接口、实现和算法
2.了解集合框架的具体优点并通过以后的代码能够深刻认识
◆减少编程工作量-它可以提供有用的数据结构和算法,从而使程序员不必自己编写。
◆提高性能-它可以提供有用的数据结构和算法的高性能实现。
因为每个接口的不同实现是可以互换的,所以可通过交换实现方便地调整程序。
并且集合算法是经过验证的,所以效率也是很高的。
◆实现无关API间的互操作-它可以建立一种公用语言,用于来回传递。
在前面我们知道通过一个方法可以实现一个对象传递,但如果是一组对象传递怎么办呢?
就可以使用集合进行传递,先把对象放在集合中,再把对象作为传输。
◆减少学习API所需的劳动-用户没有必要学习多个不同的集合API。
因为集合框架实现了继承关系,所有有很大一部分共性。
◆减少设计和实现API所需的工作量-没有必要生成多个不同的集合API。
◆有助于软件重用-提供集合与算法的标准接口,便于对其进行操作
集合和数组的区别:
1、集合只能放置对象,数组中可以是对象数组,也可以是基本数据类型数组。
2、数组只能放置同一种数据类型,对于集合而言,里面元素可以是不同类型的元素
3、集合对象长度可以随着元素的多少发生变化,而数组一旦指定了容量,长度就不能发生改变。
4、集合中提供了很丰富的算法方法,而数组里的方法很有限。
采用集合对数据的操纵会很容易。
3.集合框架的结构。
3-1.接口----代表要做什么
Collection是上级接口ListSet是它的子接口而Map是JDK1.2引进的另外一个接口和Collection没有关系
3-2.实现接口的类----代表怎么去做
主要掌握图中黑线的
3-3.算法类
对集合元素的遍历(将集合里的元素一个个地取出来):
:
Iterator
常用算法操作:
CollectionsArrays比较器
集合框架都有一个初始长度:
ArrayList、Vector都是10。
HashSet、HashMap是16。
在集合中可以放置任何数据类型的对象。
在取出来的时候,都会是一个Object类型。
4.掌握Collection接口里提供的基本操作方法这些方法在子接口以及其实现类中都是通用的
添加:
voidadd
//将元素添加到集合中
Collectioncon=newArrayList();//集合接接口不能直接实例化,必须指向一个实现了接口的类对象。
con.add(“abc”)//加入元素至集合
在JDK1.5以后加入了自动装箱的功能。
这样集合允许书写加入基本数据类型。
在加入之前先将基本数据类型转为相对应的包装类,再做添加。
con.add
(1);//等价于con.add(newInteger
(1));
元素是否存在:
booleancontains
使用这个方法可用于判断当前元素是否在集合中已经存在。
使用时要注意,因为用于判断时默认是判断当前这个对象是否存在,是通过equals()方法进行比较,默认是比较地址。
如果是内容的比较,则需要重写equals()方法。
publicclassStudent{
privateintid;
privateStringname;
Student(intid,Stringname){
this.id=id;
this.name=name;
}
publicstaticvoidmain(String[]args){
ArrayListlist=newArrayList();
list.add(newStudent(1,"abc"));
System.out.println(list.contains(newStudent(1,"abc")));
}
这个时候打出的是false。
因为我们在进行查询时,默认是看传入的对象存不存在,比较地址。
所以很明显,加入集合的元素和检查的元素是两个对象。
所以尽管它们的内容完全一样,返回的也是false。
解决方法:
在Student类里重写equals()方法。
利用eclipse工具可自动生成。
publicbooleanequals(Objectobj){
if(this==obj)
returntrue;
if(obj==null)
returnfalse;
if(getClass()!
=obj.getClass())
returnfalse;
finalStudentother=(Student)obj;
if(id!
=other.id)
returnfalse;
if(name==null){
if(other.name!
=null)
returnfalse;
}elseif(!
name.equals(other.name))
returnfalse;
returntrue;
}
这时候进行比较时,比较的就是内容了。
再执行上面的代码,返回一个true
删除:
remove
从对象中移除对象。
这个方法实现了方法重载
remove
(1);//以下标做为参数进行移除,这里移除第二个元素
remove(“abc”);//以对象做为参数进行移除,这里移除对象为”abc”的元素
替换元素:
Objectset(intindex,Objectelement)
这个方法是以新的对象替换指定下标的元素,返回原来的对象引用
ArrayListlist=newArrayList();
list.add(“2”);
Objectinfo=list.set(0,”4”);
System.out.println(list.get(0)+””+info);
结果是42。
因为在集合中把第一个元素的引用指向了”4”这个对象。
而返回的是原来的对象”2”的引用。
获得Iterator对象:
iterator
获得Iterator迭代器对象。
(用于集合遍历)(详细见后面示例)
获得集合的长度(集合中元素的个数):
intsize(必须掌握)
ArrayListlist=newArrayList();
list.add(“1”);
list.add(“2”);
list.add(“3”);
System.out.println(list.size());
结果是3;表示数组里有3个元素
移除集合所有元素:
voidclear
ArrayListlist=newArrayList();
list.add(“1”);
list.add(“2”);
list.add(“3”);
list.clear();
System.out.println(list.size());
结果是0;通过clear方法,集合中元素已经清空。
判断集合中是否有元素:
voidisEmpty
ArrayListlist=newArrayList();
System.out.println(list.isEmpty());
结果是true。
因为集合中没有元素存在。
如果集合中有元素存在返回false。
当然也可以用list.size()==0判断集合长度的方法达到相同的效果。
将集合转化为数组:
Object[]toArray()
ArrayListlist=newArrayList();
list.add(“1”);
list.add(“2”);
list.add(“3”);
Object[]obj=list.toArray();
将list集合转为Object数组
5.Set接口
5-1.不能有重复元素(也需要重写equals()方法)
5-2是无序的集合,放入Set里的元素并不是以放入顺序来决定的。
使用LinkedHashSet可以实现以放入顺序来排列集合
5-3.放进TreeSet里的元素会自动排序(升序)。
不能放复杂类型的对象进入TreeSet
6.List接口
6-1.以线形方式存储对象。
List接口提供get(intch)方式方便的对集合中元素的访问。
6-2.ArrayList索引(遍历根据下标获得元素)快,但除了对末尾的元素的添加和删除以外其他效率都很低,多用于查询(因为ArrayList底层利用的是数组操作,所以在内存中是连续的空间,所以添加到末尾快,查询速度快;但从中间删除和插入效率低)
6-3.LinkedList在内存中是一个不连续的空间,所以删除插入更新快,但索引慢
扩展知识(现在了解就可以):
ArrayList,Vector,LinkedList的存储性能和区别
ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
7.Map接口
7-1.集合里的每个元素都是1对对象(键值对映射),
添加元素采用put方法
HashMapmap=newHashMap();
map.put("1",newMan(10,"周青"));
ObjectobjMan=map.get("1");//根据键,获得值
Manman=(Man)objMan;//将值强转为Man类型
System.out.println(map.containsKey("32"));//判断有当前键的对象是否存在
System.out.println(map.containsValue(newMan(10,"丁汉")));//判断有当前值的对象是否存在
7-2.键不能重复值可以
扩展知识:
HashMap和HashTable的区别(现在了解就可以):
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都实现了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。
因为contains方法容易让人引起误解。
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Mapinterface的一个实现。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap就必须为之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。
8、泛型的使用。
在集合中可以放置任何数据类型的对象。
在取出来的时候,都会是一个Object类型。
所以在使用之前,通常把它强转为我们想要的类型(String)list.get(i),以便调用其中的方法。
但有些时候,我们想让我们的集合只能放置一种数据类型,便于我们对集合规范的时候,就可以使用泛型。
其语法如下:
ArrayList
这样的集合只能放置String类型的对象。
其余的对象加不进去。
使用泛型时,不但可以规范集合,而且使用也非常放便。
因为它里面取出来的数据类型就是定义泛型时的数据类型,不需要我们进行对象的强转。
代码示例:
不使用泛型:
ArrayListlist=newArrayList;
list.add(“ew”);
Stringtemp=(String)list.get(0);//强转为String类型
System.out.println(temp.length());//打印第一个元素的长度
使用泛型:
ArrayList
list.add(“ew”);
System.out.println(list.get(0).length());//不需强转直接调用其中方法
9、集合的遍历。
集合的遍历有三种方式:
a、for循环遍历(只适用于List接口类)
ArrayList
1ist.add
(1);
for(intI=0;I Stringtemp=(String)list.get(i); System.out.println(temp.length()); } b、for-each循环遍历(JDK1.5版本,只能从头遍历到尾) HashSet for(Stringtemp: set){ System.out.println(temp.length()); } c、使用迭代器循环遍历(只能从头遍历到尾) HashSetset=newHashSet(); Iteratorit=set.iterator();//获得迭代器对象 while(it.hasNext()){//判断是否有下一个元素,没有返回false Stringtemp=(String)it.next();//获得下一个元素对象 System.out.println(temp.length()); } Map接口对象遍历 HashMapmap=newHashMap(); Setset=map.entrySet();//得到键值对Set对象,里面的值都是Map.Entry类型 for(Objectobj: set){//遍历这个Set对象 Map.Entryentry=(Map.Entry)obj; System.out.print("键: "+entry.getKey()+""); System.out.println("值: "+entry.getValue()); } 10、集合算法类(Collections和Arrays) 这两个类都是用于数据的操作类。 其中Collections主要用于集合操作,Arrays主要用于数组操作。 因为集合的使用泛围比数组广泛得多,所以我们主要关注Collections类。 注意和Collection区别。 Collection是接口,而Collections是类。 在对集合数据进行操作时,注意equals()方法的重写 //以下代码使用的Man这个类,都在这里定义 publicclassMan{ intage; Stringname; publicMan(intage1,Stringname1){ this.age=age1; this.name=name1; } publicMan(Stringname){ this.name=name; } publicbooleanequals(Objectobj){ …………………… } } 1、集合的排序 简单对象的排序。 只需要使用Collections的sort方法就行了。 代码示例: ArrayListlist=newArrayList(); list.add(“11”); list.add(“2”); list.add(“33”); Connections.sort(list); System.out.println(list); 结果是2,11,33 对于复杂对象的排序,则需要单独写一个类实现Comparator接口,并重写其中intcompare(To1,To2)方法。 代码示例: publicclassListSort{ publicstaticvoidmain(String[]args){ ArrayListlist=newArrayList(); list.add(newMan(12,"33")); list.add(newMan(10,"rr")); list.add(newMan(18,"aa")); Collections.sort(list,newSorts(0));//按年龄排序 Collections.sort(list,newSorts (1));//按姓名排序 for(Objectobj: list){ System.out.println(((Man)obj).getAge()); } } } classSortsimplementsjava.util.Comparator{ privateintterm; Sorts(intterm){ this.term=term; } publicintcompare(Objecto1,Objecto2){ Manm1=(Man)o1;//将比较对象强转为Man类型 Manm2=(Man)o2; /** *指定排序规则 */ if(term==0){//按年龄排序 returnm1.age-m2.age; } else{//按姓名排序 returnpareTo(m2.name); } } } 2、数据的搜索(使用binarySearch,返回当前对象的下标,未找到返回-1,注意这个方法使用前,必须对集合进行排序,以及Man这个类equals()方法的重写) publicclassArrayTest{ publicstaticvoidmain(String[]args){ ArrayListlist=newArrayList(); list.add(newMan("aaa",123)); list.add(newMan("bbb",93)); list.add(newMan("ccc",33)); Manman=newMan("bbb");//要查找的对象,注意,这时候只把对象的name初始化。 在调用binarySearch方法的时候,会把有当前name值的对象下标返回 Collections.sort(list,newSort());//按姓名升序 inti=Collections.binarySearch(list,man,newSort());//指定要查找的对象,并指定按姓名查找。 System.out.println(i); } } classSortimplementsjava.util.Comparator{ publicintcompare(Objecto1,Objecto2){ Manm1=(Man)o1; Manm2=(Man)o2; returnm1.getName().compareTo(m2.getName()); } } 利用Map搜索会很容易,只需通过键获得相应的值对象就行了。 不过,这种方式灵活性差一些。 publicclassSearchMap{ staticHashMapmap=newHashMap(); publicstaticvoidmain(String[]args){ map.put("严大开1",newMan(20,"严大开1")); map.put("严大开2",newMan(24,"严大开2" map.put("严大开89",newMan(10,"严大开89")); map.put("严大开7",newMan(70,"严大开7"));)); map.put("严大开4",newMan(16,"严大开4")); Objectobj=map.get("严大开4");//根据键,获得值 Manman=(Man)obj;//将值强转 System.out.println(man.getName()+""+man.getAge()); } } 3、数据的重排: shuffle(Listlist) ArrayListlist=newArrayList(); list.add(“1”); list.add(“2”); list.add(“3”); Collections.shuffle(list); 这时数据就是一个乱序的顺序。 11.了解Stack的特性后进先出(联系洗碗或汗洛塔游戏) 对集合操作的总结: 1.操作方法 1-1.通用的: addremovecontains 1-2.特殊的: 针对Mapput 2.遍历方法 2-1.只要提供了get获得元素和size获得集合长度就能通过简单的for循环直接取得每个元素 2-2.如果没有提供,则考虑用I
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 集合 知识点