一,什么是集合

集合是由多元素组成的一组数组
提供了一套性能优良、使用方便的接口和类位于Java.util包中
集合中的元素全部是对象,即Object类的实例()
不同的集合类有什么不同的功能和特点,适合不同的场合

1.1为什么要用集合:

集合弥补了数组的缺陷,比数组跟灵活,可以提高软件的开发效率,不同的集合可以应用在不同的场合 而且可以存储任意类型的值
注意:
集合中为什么可以存储任意类型的值:应为它是把传递进来的时候强制把值转换成了Object类型(这个也属于一个弊端,因为要进行频繁的转换)
值类型 引用类型 装箱拆箱
1.2、什么时候用集合:
如果并不知道程序运行时会需要多少对象,或者需要更复杂方式存储对象,可以使用Java集合框架
1.3、怎么用集合:
集合类主要Collction和Map接口派生而来通过实例化他们的实例类使用即可
1.4、集合的优点:
灵活、提高了代码运行效率、可存放任意类型的值
1.5、集合和数组的区别:
JavaOOP 集合 - 图1
数组:长度固定不变、只能存放相同类型的值
集合:长度可以改变。可以存放不同类型的值
2、Collction接口:
Collection接口存储一组可重复且没有顺序的对象
2.1、Collction接口的方法:
JavaOOP 集合 - 图2
在输出时系统会调用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) 截取颔首不含尾

JavaOOP 集合 - 图3
2.2.4、ArrayList集合类(实现了List接口)的使用方法:
ArratList和数组类似,也是用一个下标代表一个值,访问也可呀通过下标(从0开始)
代码展示:

  1. //添加元素的方法和删除的方法
  2. List list=new ArrayList();
  3. list.add("李四");
  4. list.add("王五");
  5. list.add("李三");
  6. System.out.println(list);//输出集合
  7. list.add(0,"张三");//在0下标添加一个值
  8. System.out.println(list);//输出
  9. list.remove("李四");//删除值为李四的区间
  10. list.remove(1);//删除下标为1的值
  11. System.out.println(list);//输出
  12. System.out.println(list.get(0));
  13. for (int i = 0; i < list.size(); i++) {
  14. System.out.println(list.get(i));
  15. }

JavaOOP 集合 - 图4
注意:在ArratList进行新增和删除时,下标会自动更新
如 0下标的值为张三
1下标的值为李四
2下标的值为王五
此时把张三删除掉,则系统自动会把下标更新,所以之后0下标中的值就是李四,1下标中的值就是王五
此时如用add()方法添加的是一个对象的则遍历时需要转型
代码展示:

  1. //创建四个狗狗对象
  2. Dog d=new Dog("欧欧","雪瑞纳");
  3. Dog d1=new Dog("亚亚","拉布拉多");
  4. Dog d2=new Dog("美美","雪纳瑞");
  5. Dog d3=new Dog("菲菲",";拉布拉多");
  6. Dog d4=new Dog("欣欣","吉娃娃");
  7. //创建ArrayList集合
  8. List li=new ArrayList();
  9. li.add(d);
  10. li.add(d1);
  11. li.add(d2);
  12. li.add(d3);
  13. li.add(d4);
  14. //删除第三个元素
  15. li.remove(3);
  16. //输出狗狗的数量
  17. System.out.println("狗狗的数量时:"+li.size());
  18. System.out.println("分别是");
  19. System.out.println("用for遍历");
  20. for(int i=0;i<li.size();i++){
  21. Dog dog=(Dog)li.get(i);//转型 由于List集合中存放的都是Object类的都西昂
  22. 所已要强制类型转换
  23. 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() 删除并返回链表中的最后一个元素

使用方法:
代码:

  1. /**
  2. * 狗类
  3. */
  4. public class Dog {
  5. private String name;/**狗的名字*/
  6. private String brand;/**品种*/
  7. public String getName() {
  8. return name;
  9. }
  10. public void setName(String name) {
  11. this.name = name;
  12. }
  13. public String getBrand() {
  14. return brand;
  15. }
  16. public void setBrand(String brand) {
  17. this.brand = brand;
  18. }
  19. /**
  20. * 类的无参构造方法
  21. */
  22. public Dog() {
  23. }
  24. /**
  25. * 类的有参构造方法
  26. * @param name
  27. * @param brand
  28. */
  29. public Dog(String name, String brand) {
  30. this.name = name;
  31. this.brand = brand;
  32. }
  33. }
  34. //创建四个狗狗对象
  35. Dog d3=new Dog("菲菲",";拉布拉多");
  36. Dog d=new Dog("欧欧","雪瑞纳");
  37. Dog d1=new Dog("亚亚","拉布拉多");
  38. Dog d2=new Dog("美美","雪纳瑞");
  39. //创建集合
  40. LinkedList lik=new LinkedList();
  41. lik.add(d3);
  42. lik.add(d);
  43. lik.add(d1);
  44. lik.add(d2);
  45. Dog dog=(Dog)lik.getFirst();//拿到集合中的第一个元素
  46. Dog dog2=(Dog)lik.getLast();//拿到集合中的最后de元素
  47. System.out.println("第一天狗叫"+dog.getName());
  48. System.out.println("第最后狗叫"+dog2.getName());
  49. lik.removeFirst();//删除第一个元素
  50. lik.removeLast();//删除最后一个元素
  51. System.out.println("删除部分的狗时");
  52. System.out.println("还有"+lik.size()+"条");
  53. Iterator it=lik.iterator();
  54. while(it.hasNext()){
  55. Dog dog44=(Dog)it.next();//转型
  56. System.out.println(dog44.getName()+"\t"+dog44.getBrand());

运行结果:
JavaOOP 集合 - 图5
2.4.ArrayList和LinkedList的区别
ArrayList类和LinkedList类的共同点
可以容纳所有类型的元素对象,包括null
元素值可以重复
元素按顺序存储
ArrayList类特点
底层是数组
优点:基于数组实现,读取操作效率高
缺点:不适合频繁进行插入和删除操作,因为每次执行该类操作都需要频繁移动其中的元素
LinkedList类特点
由双向链表实现,任意一个节点都可以方便地访问它的前驱节点和后继节点
优点:增加、删除操作只需修改链表节点指针,不需进行频繁的移动
缺点:遍历效率较低
3.Set接口
和List接口一样,也是Collection的子接口
集合里的多个对象之间没有明显的顺序
不允许包含重复的元素
与Collection接口基本一样,没有提供额外的方法,只是行为上略有不同
继承关系:
JavaOOP 集合 - 图6
3.1HashSet类
说明:是Set接口的典型实现,可以实现对无序不重复数据的存储,具有很好的存取和查找性能
特征:
不允许存储重复的元素
没有索引,没有包含索引的方法,不能使用索引遍历
无序集合,存储元素和取出元素的顺序可能不一致
不能使用索引进行遍历
使用方式:

  1. public class HashSetDemo {
  2. public static void main(String[] args) {
  3. Set ss=new HashSet();
  4. System.out.println( ss.add("11"));//添加值 添加成功返回true防止false
  5. System.out.println( ss.add("11"));//检测是否可以添加相同的值
  6. //创建迭代器对象
  7. Iterator<String> it=ss.iterator();
  8. while(it.hasNext()){
  9. System.out.println(it.next());
  10. }
  11. }

运行结果:
JavaOOP 集合 - 图7
3.2List和Set的区别
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。
JavaOOP 集合 - 图8
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使用方法特别情况:

  1. mm.put("a","e");
  2. mm.put("a","w");

JavaOOP 集合 - 图9
HashMap使用方法

  1. Map mm=new HashMap();
  2. mm.put("a","e");
  3. mm.put("a","w");
  4. System.out.println(mm);
  5. mm.put("c","q");
  6. //输出所有key
  7. System.out.println(mm.keySet());
  8. //输出所有values
  9. System.out.println(mm.values());
  10. //输出key-values
  11. System.out.println(mm);
  12. //遍历key
  13. for(Object obj:mm.keySet()){
  14. System.out.println(obj);
  15. }
  16. //遍历values
  17. for(Object obj:mm.values()){
  18. System.out.println(obj);
  19. }
  20. //一起遍历
  21. for(Object obj:mm.entrySet()){
  22. System.out.println(obj);

特点:
存储成对出现的“键-值对”元素
如:京—北京市
一个Map对象由若干个“键-值对”组成
优势:查询指定元素效率高
4.1Map.Entry接口
用于保存“键-值对”元素
运用Map.Entry接口遍历集合
通过entrySet()方法获取所有“键-值”对元素的集合
遍历集合中每个元素,进行键和值的分离
4.2Map和Map.Entry接口的联合使用

  1. Map<String, String> mm=new HashMap();
  2. mm.put("菲菲","拉布拉多");
  3. mm.put("亚亚","拉布拉多");
  4. mm.put("欣欣","吉娃娃");
  5. mm.put("美美","雪纳瑞");
  6. Set<String> ss=mm.keySet();//把键值放到Set集合中
  7. System.out.println("用迭代器遍历");
  8. Iterator<String> it=ss.iterator();
  9. while(it.hasNext()){
  10. String key=(String)it.next();
  11. String name=mm.get(key);//把值放入到name中
  12. System.out.println(key+"\t"+name);
  13. }
  14. System.out.println("用froech循环");
  15. //用到了Map.Entry接口
  16. for (Map.Entry<String,String> m: mm.entrySet()) {
  17. System.out.println(m.getKey()+"\t"+m.getValue());
  18. }

5.迭代器:
用处:遍历集合
常见方法:

方法 描述
boolean hasNext() 是否存在下一个迭代元素,存在则返回true
Object next() 返回迭代的下一个元素
void remove() 删除集合里上一次next()方法返回的元素

注意事项:
Iterator的使用必依赖于Collection对象
Iterator仅用于遍历集合,并不提供储存数据的功能
使用Iterator迭代访问Collection集合时,可调用Iterator的remove()方法删除集合元素
使用Iterator对集合元素进行迭代时,是把集合元素的值传给迭代器,因此,删除迭代器中存储的值不会影响集合中保存的元素
代码展示:

  1. Collection cc=new HashSet();
  2. Fruit ff=new Fruit("香水梨",2.5);
  3. Fruit ff1=new Fruit("苹果梨",2.0);
  4. Fruit ff3=new Fruit("富士苹果",3.5);
  5. Fruit ff4=new Fruit("金帅苹果",3.0);
  6. cc.add(ff);
  7. cc.add(ff1);
  8. cc.add(ff3);
  9. cc.add(ff4);
  10. //输出结果
  11. // System.out.println(cc);
  12. //获取迭代器
  13. Iterator it=cc.iterator();
  14. while(it.hasNext()){
  15. Fruit fruit=(Fruit)it.next();
  16. fruit.show();

错误示范:
对Collection集合进行遍历操作时,其中的元素不能被改变

  1. Iterator it = fruitList.iterator();
  2. while(it.hasNext()) {
  3. Fruit fruit = (Fruit)it.next();
  4. if(fruit.brand.equals("苹果梨")) {
  5. fruit.remove();//这是直接用集合名点的将会影响到集合
  6. } else {
  7. fruit.show();
  8. }
  9. }

产生的异常:不可以在遍历式改变集合
JavaOOP 集合 - 图10
6.foreach遍历数组
foreach循环
JDK1.5引入的语法结构,也称为增强for循环
可用于遍历集合和数组
语法:
JavaOOP 集合 - 图11
代码展示:

  1. 使用foreach循环遍历水果品类集合
  2. for(Object obj:fruits) {
  3. Fruit fruit = (Fruit)obj;

输出结果
JavaOOP 集合 - 图12
与Iterator接口类似,foreach循环中迭代变量也不是集合元素本身,系统只是依次把集合元素的值赋给迭代变量。因此,在foreach循环中修改迭代变量的值也没有任何实际意义
7.结构图于继承图
JavaOOP 集合 - 图13
JavaOOP 集合 - 图14
JavaOOP 集合 - 图15
JavaOOP 集合 - 图16
常用的式左边
JavaOOP 集合 - 图17
常用的式左边
JavaOOP 集合 - 图18