一,什么是集合
集合是由多元素组成的一组数组
提供了一套性能优良、使用方便的接口和类位于Java.util包中
集合中的元素全部是对象,即Object类的实例()
不同的集合类有什么不同的功能和特点,适合不同的场合
1.1为什么要用集合:
集合弥补了数组的缺陷,比数组跟灵活,可以提高软件的开发效率,不同的集合可以应用在不同的场合 而且可以存储任意类型的值
注意:
集合中为什么可以存储任意类型的值:应为它是把传递进来的时候强制把值转换成了Object类型(这个也属于一个弊端,因为要进行频繁的转换)
值类型 引用类型 装箱拆箱
1.2、什么时候用集合:
如果并不知道程序运行时会需要多少对象,或者需要更复杂方式存储对象,可以使用Java集合框架
1.3、怎么用集合:
集合类主要Collction和Map接口派生而来通过实例化他们的实例类使用即可
1.4、集合的优点:
灵活、提高了代码运行效率、可存放任意类型的值
1.5、集合和数组的区别:
数组:长度固定不变、只能存放相同类型的值
集合:长度可以改变。可以存放不同类型的值
2、Collction接口:
Collection接口存储一组可重复且没有顺序的对象
2.1、Collction接口的方法:
在输出时系统会调用toString方法
2.2、List接口:
Set接口继承了Collcetion接口可以存储:一组不可以重读且没有顺序的对象
List接口继承了Collection接口可以存储:一组可以重复且有顺序的对象
2.2.1、List接口:
继承Collection接 口,存储一组可重复的有序对象
元素顺序以元素插入的次序来放置元素,不会重新排序
通过索引访问数组元素,索引从0开始
根据索引操作集合元素的方法
2.2.2、List接口的实现类
ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素
LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素
2.2.3方法如下:
在继承了父类接口Collection的方法上拓张了一些自己特有的方法
| 方法 | 说明 |
|---|---|
| void add(int index, Object o) | 将元素插入到指定位置 |
| boolean addAll(int index, Collection c) | 将集合c所有元素插入到List集合中的指定位置 |
| Object get(int index) | 返回索引处的元素 |
| int indexOf(Objcet o) | 返回对象o在List集合中第一次出现的地方 |
| int lastIndexOf(Objcet o ) |
最后一次出现的地方 |
| Object remove(int index) | 删除索引指定的元素 |
| boolean remove(Object) | 从集合中删除指定元素 |
| Object set(int index, Object ele) | 将索引的值替换成 ele对象 |
| List subList(int fromIndex, int toIndex) | 截取颔首不含尾 |

2.2.4、ArrayList集合类(实现了List接口)的使用方法:
ArratList和数组类似,也是用一个下标代表一个值,访问也可呀通过下标(从0开始)
代码展示:
//添加元素的方法和删除的方法List list=new ArrayList();list.add("李四");list.add("王五");list.add("李三");System.out.println(list);//输出集合list.add(0,"张三");//在0下标添加一个值System.out.println(list);//输出list.remove("李四");//删除值为李四的区间list.remove(1);//删除下标为1的值System.out.println(list);//输出System.out.println(list.get(0));for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}

注意:在ArratList进行新增和删除时,下标会自动更新
如 0下标的值为张三
1下标的值为李四
2下标的值为王五
此时把张三删除掉,则系统自动会把下标更新,所以之后0下标中的值就是李四,1下标中的值就是王五
此时如用add()方法添加的是一个对象的则遍历时需要转型
代码展示:
//创建四个狗狗对象Dog d=new Dog("欧欧","雪瑞纳");Dog d1=new Dog("亚亚","拉布拉多");Dog d2=new Dog("美美","雪纳瑞");Dog d3=new Dog("菲菲",";拉布拉多");Dog d4=new Dog("欣欣","吉娃娃");//创建ArrayList集合List li=new ArrayList();li.add(d);li.add(d1);li.add(d2);li.add(d3);li.add(d4);//删除第三个元素li.remove(3);//输出狗狗的数量System.out.println("狗狗的数量时:"+li.size());System.out.println("分别是");System.out.println("用for遍历");for(int i=0;i<li.size();i++){Dog dog=(Dog)li.get(i);//转型 由于List集合中存放的都是Object类的都西昂所已要强制类型转换System.out.println(dog.getName()+"\t"+dog.getBrand());
注意事项:
可以使用索引访问List集合元素
可以使用for循环遍历List集合
List集合中存放的都是Object类对象
add(Object o)方法的参数是Object类对象
在通过get(int i)方法获取元素时必须进行强制类型转换
如:Dog dog=(Dog)li.get(i);
删除集合元素的方法
按索引删除
按对象删除
调用set(int index,Object o)方法改变List集合指定索引的元素时,指定的索引必须是List集合的有效索引
set(int index,Object o)方法不会改变List集合的长度
2.3、LinkedList集合类
具有双向链表结构,更加方便实现添加和删除操作
除了具有List接口扩展的方法外,还提供了实现链表操作的方法
| 方法名 | 说明 |
|---|---|
| void addFirst(Object o) | 在链表的首部添加元素 |
| void addLast(Object o) | 在链表的末尾添加元素 |
| Object getFirst() | 返回链表中第一个元素 |
| Object getLast() | 返回链表中最后一个元素 |
| Object removeFirst() | 删除并返回链表中的第一个元素 |
| Object removeLast() | 删除并返回链表中的最后一个元素 |
使用方法:
代码:
/*** 狗类*/public class Dog {private String name;/**狗的名字*/private String brand;/**品种*/public String getName() {return name;}public void setName(String name) {this.name = name;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}/*** 类的无参构造方法*/public Dog() {}/*** 类的有参构造方法* @param name* @param brand*/public Dog(String name, String brand) {this.name = name;this.brand = brand;}}//创建四个狗狗对象Dog d3=new Dog("菲菲",";拉布拉多");Dog d=new Dog("欧欧","雪瑞纳");Dog d1=new Dog("亚亚","拉布拉多");Dog d2=new Dog("美美","雪纳瑞");//创建集合LinkedList lik=new LinkedList();lik.add(d3);lik.add(d);lik.add(d1);lik.add(d2);Dog dog=(Dog)lik.getFirst();//拿到集合中的第一个元素Dog dog2=(Dog)lik.getLast();//拿到集合中的最后de元素System.out.println("第一天狗叫"+dog.getName());System.out.println("第最后狗叫"+dog2.getName());lik.removeFirst();//删除第一个元素lik.removeLast();//删除最后一个元素System.out.println("删除部分的狗时");System.out.println("还有"+lik.size()+"条");Iterator it=lik.iterator();while(it.hasNext()){Dog dog44=(Dog)it.next();//转型System.out.println(dog44.getName()+"\t"+dog44.getBrand());
运行结果:
2.4.ArrayList和LinkedList的区别
ArrayList类和LinkedList类的共同点
可以容纳所有类型的元素对象,包括null
元素值可以重复
元素按顺序存储
ArrayList类特点
底层是数组
优点:基于数组实现,读取操作效率高
缺点:不适合频繁进行插入和删除操作,因为每次执行该类操作都需要频繁移动其中的元素
LinkedList类特点
由双向链表实现,任意一个节点都可以方便地访问它的前驱节点和后继节点
优点:增加、删除操作只需修改链表节点指针,不需进行频繁的移动
缺点:遍历效率较低
3.Set接口
和List接口一样,也是Collection的子接口
集合里的多个对象之间没有明显的顺序
不允许包含重复的元素
与Collection接口基本一样,没有提供额外的方法,只是行为上略有不同
继承关系:
3.1HashSet类
说明:是Set接口的典型实现,可以实现对无序不重复数据的存储,具有很好的存取和查找性能
特征:
不允许存储重复的元素
没有索引,没有包含索引的方法,不能使用索引遍历
无序集合,存储元素和取出元素的顺序可能不一致
不能使用索引进行遍历
使用方式:
public class HashSetDemo {public static void main(String[] args) {Set ss=new HashSet();System.out.println( ss.add("11"));//添加值 添加成功返回true防止falseSystem.out.println( ss.add("11"));//检测是否可以添加相同的值//创建迭代器对象Iterator<String> it=ss.iterator();while(it.hasNext()){System.out.println(it.next());}}
运行结果:
3.2List和Set的区别
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。
4.Map接口:
Map接口专门处理键值映射数据的存储
根据键(key)实现对值(value)的操作
Key:不要求有序,不允许重复
Value:不要求有序,但允许重复
与Collection接口不存在继承关系
常见方法:
| 方法 | 描述 |
|---|---|
| Object put(Object key,Object value) | 以“键-值对”的方式进行存储 |
| Object get(Object key) | 返回指定键所对应的值。如果不存在指定的键,返回null |
| int size() | 返回元素个数 |
| boolean remove(Object key) | 删除指定的键映射的“键-值对” |
| Set keyset() | 返回键的集合 |
| Collection values() | 返回值的集合 |
| boolean containsKey(Object key) | 如果存在指定的键映射的“键-值对”,则返回true |
| Set entrySet() | 返回“键-值对”集合 |
| boolean isEmpty() | 若不存在“键-值对”元素,则返回true |
| void clear() | 删除该Map对象中的所有“键-值对” |
HashMap使用方法特别情况:
mm.put("a","e");mm.put("a","w");

HashMap使用方法
Map mm=new HashMap();mm.put("a","e");mm.put("a","w");System.out.println(mm);mm.put("c","q");//输出所有keySystem.out.println(mm.keySet());//输出所有valuesSystem.out.println(mm.values());//输出key-valuesSystem.out.println(mm);//遍历keyfor(Object obj:mm.keySet()){System.out.println(obj);}//遍历valuesfor(Object obj:mm.values()){System.out.println(obj);}//一起遍历for(Object obj:mm.entrySet()){System.out.println(obj);
特点:
存储成对出现的“键-值对”元素
如:京—北京市
一个Map对象由若干个“键-值对”组成
优势:查询指定元素效率高
4.1Map.Entry接口
用于保存“键-值对”元素
运用Map.Entry接口遍历集合
通过entrySet()方法获取所有“键-值”对元素的集合
遍历集合中每个元素,进行键和值的分离
4.2Map和Map.Entry接口的联合使用
Map<String, String> mm=new HashMap();mm.put("菲菲","拉布拉多");mm.put("亚亚","拉布拉多");mm.put("欣欣","吉娃娃");mm.put("美美","雪纳瑞");Set<String> ss=mm.keySet();//把键值放到Set集合中System.out.println("用迭代器遍历");Iterator<String> it=ss.iterator();while(it.hasNext()){String key=(String)it.next();String name=mm.get(key);//把值放入到name中System.out.println(key+"\t"+name);}System.out.println("用froech循环");//用到了Map.Entry接口for (Map.Entry<String,String> m: mm.entrySet()) {System.out.println(m.getKey()+"\t"+m.getValue());}
5.迭代器:
用处:遍历集合
常见方法:
| 方法 | 描述 |
|---|---|
| boolean hasNext() | 是否存在下一个迭代元素,存在则返回true |
| Object next() | 返回迭代的下一个元素 |
| void remove() | 删除集合里上一次next()方法返回的元素 |
注意事项:
Iterator的使用必依赖于Collection对象
Iterator仅用于遍历集合,并不提供储存数据的功能
使用Iterator迭代访问Collection集合时,可调用Iterator的remove()方法删除集合元素
使用Iterator对集合元素进行迭代时,是把集合元素的值传给迭代器,因此,删除迭代器中存储的值不会影响集合中保存的元素
代码展示:
Collection cc=new HashSet();Fruit ff=new Fruit("香水梨",2.5);Fruit ff1=new Fruit("苹果梨",2.0);Fruit ff3=new Fruit("富士苹果",3.5);Fruit ff4=new Fruit("金帅苹果",3.0);cc.add(ff);cc.add(ff1);cc.add(ff3);cc.add(ff4);//输出结果// System.out.println(cc);//获取迭代器Iterator it=cc.iterator();while(it.hasNext()){Fruit fruit=(Fruit)it.next();fruit.show();
错误示范:
对Collection集合进行遍历操作时,其中的元素不能被改变
Iterator it = fruitList.iterator();while(it.hasNext()) {Fruit fruit = (Fruit)it.next();if(fruit.brand.equals("苹果梨")) {fruit.remove();//这是直接用集合名点的将会影响到集合} else {fruit.show();}}
产生的异常:不可以在遍历式改变集合
6.foreach遍历数组
foreach循环
JDK1.5引入的语法结构,也称为增强for循环
可用于遍历集合和数组
语法:
代码展示:
使用foreach循环遍历水果品类集合for(Object obj:fruits) {Fruit fruit = (Fruit)obj;
输出结果
与Iterator接口类似,foreach循环中迭代变量也不是集合元素本身,系统只是依次把集合元素的值赋给迭代变量。因此,在foreach循环中修改迭代变量的值也没有任何实际意义
7.结构图于继承图



常用的式左边
常用的式左边
