一、集合简介

Java Collections Framework (JCF) ,集合: 是一个装东西的容器
之前我们已经学过一种集合(数组),只是数组有一定的缺陷:长度不可改变,内容固定
图片11.png
Java的所有集合,都在java.util包下
如果按照3个方法:允许不允许放置重复元素,集合中元素中元素是否有序,是否允许放置null元素,我们可以将集合体系划分为2大体系

Collection (List与Set)
Map

1.1 List列表

特点:集合中元素可以重复,而且元素的排序是按照一定的顺序进行排列的

1.2 Set集

特点:集合中元素不能重复,而且元素的排序是无序的

1.3 Map(映射集)

特点:集合中的所有元素都是按照 key - value 的结构进行存放,而且key不允许重复,value可以重复

二、Collection集合

在集合框架中,集合(Collection)接口位于Set接口和List接口的最顶层,是Set接口和List接口的父接口。
Collection接口中的主要方法:
图片11.png
Iterator接口中的主要方法:
图片11.png

2.1 List集合

List接口继承自Collection接口,它的子类一定都提供了所有Collection接口中的所有方法的实现。
List集合的特点:
1、List中的元素是有顺序的。
2、List通常允许重复元素。
3、List的实现类通常支持null元素。
4、可以通过索引(下标)访问List对象容器中的元素。
List接口的扩展的方法:
图片11.png

2.1.1 ArrayList集合

ArrayList 是List的实现类,它实现了List中的所有抽象方法。它在存储数据时,采用的数据结构:数组结构
通过代码分析底层就是数组结构!
底层代码:
图片11.png

ArrayList的用法

直接new ArrayList();

  1. List list = new ArrayList();

ArrayList的常用API

  1. public class ListStudy {
  2. public static void main(String[] args) {
  3. // TODO Auto-generated method stub
  4. // study01();
  5. study02();
  6. }
  7. private static void study02() {
  8. // TODO Auto-generated method stub
  9. //指定集合中只能存放 String类型的元素
  10. List<String> data = new ArrayList<String>();
  11. data.add("隔壁老王");
  12. data.add("隔壁老张");
  13. data.add("隔壁老宋");
  14. data.add(null);
  15. //判断集合中是否存在某一个元素
  16. System.out.println(data.contains("隔壁老王"));
  17. //移除某一个元素
  18. System.out.println(data.remove("隔壁老王"));
  19. List<StudentBean> stus = new ArrayList<StudentBean>();
  20. stus.add(new StudentBean("xiaoz",98,34,12));
  21. // stus.add("隔壁小蓉");
  22. }
  23. private static void study01() {
  24. // TODO Auto-generated method stub
  25. // 创建一个ArrayList()
  26. List data = new ArrayList();
  27. // 操作集合
  28. String str = "隔壁老张";
  29. // 向集合中添加元素
  30. data.add(str);
  31. StudentBean stu = new StudentBean("刘亦菲", 99, 89, 90);
  32. data.add(stu);
  33. // 允许放置重复元素
  34. data.add(str);
  35. data.add(null);
  36. // 获取(单个单个)
  37. // System.out.println(data.get(0));
  38. // System.out.println(data.get(1));
  39. // System.out.println(data.get(2));
  40. // System.out.println(data.get(3));
  41. // 遍历(1) for 结合下标
  42. // 元素的个数
  43. // int size = data.size();
  44. // for(int i = 0; i < size; i ++) {
  45. //
  46. // System.out.println(data.get(i));
  47. // }
  48. // 遍历(2) foreach
  49. // for (Object object : data) {
  50. // if(object instanceof String) {
  51. // String string = (String)object;
  52. // System.out.println(string);
  53. // }else if(object instanceof StudentBean) {
  54. // StudentBean student = (StudentBean)object;
  55. // System.out.println(student);
  56. // }else {
  57. // System.out.println(object);
  58. // }
  59. // }
  60. // 遍历(3) 迭代器(一种专门用来遍历集合的接口)
  61. // Iterator iterator = data.iterator();
  62. // // 判断是否有下一个元素
  63. // while (iterator.hasNext()) {
  64. //
  65. // Object object = iterator.next();
  66. // //判断元素的类型
  67. // if (object instanceof String) {
  68. // String string = (String) object;
  69. // System.out.println(string);
  70. // } else if (object instanceof StudentBean) {
  71. // StudentBean student = (StudentBean) object;
  72. // System.out.println(student);
  73. // } else {
  74. // System.out.println(object);
  75. // }
  76. //
  77. // //迭代器的主要作用:除了遍历集合之外,还可以对元素进行操作
  78. // iterator.remove();
  79. // }
  80. //
  81. // 根据下标删除元素
  82. data.remove(3);
  83. // 根据元素来完成删除(第1个)
  84. data.remove(str);
  85. // 输出元素的个数
  86. System.out.println(data.size());
  87. }
  88. }

ArrayList底层细节

new ArrayList() 初始数组容量是0,然后调用add(E e)会自动扩容为 10
当超过10以后,将会发生进一步扩容,扩容是:1.5倍 依次类推……
扩容原理:使用数组的复制原理图片11.png

2.1.2 LinkedList

ArrayList 底层是数组,LinkedList的底层是链表(双向链表)
无标题.png

LinkedList 扩展的API

无标题.png
LinkedList不支持快速随机访问,如果要访问LinkedList中第n个元素,必须从头开始查找,然后跳过前面的n-1个元素。并且,虽然LinkedList也提供了一个get()方法,可以根据指定的索引来获取对应的元素,但是正因为它不支持快速随机访问,所以效率比较低下。

LinkedList的常用API

  1. /**
  2. * 链表列表
  3. * @author Administrator
  4. *
  5. */
  6. public class LinkedListStudy {
  7. public static void main(String[] args) {
  8. // TODO Auto-generated method stub
  9. LinkedList<String> data = new LinkedList<String>();
  10. data.add("a");
  11. data.add("b");
  12. data.add("c");
  13. data.add("d");
  14. data.add("e");
  15. data.add(null);
  16. //返回集合中元素的个数
  17. System.out.println(data.size());
  18. //获得最初,以及最后的一个元素
  19. System.out.println(data.getFirst());
  20. System.out.println(data.getLast());
  21. //根据下标返回元素(但是它需要先从第一个元素开始查找)
  22. System.out.println(data.get(3));
  23. //向第1个元素前,进行添加内容
  24. data.addFirst("a");
  25. //向最后一个元素,进行添加内容
  26. data.addLast("f");
  27. //遍历,如同Arraylist一样(for foreach 迭代器)
  28. Iterator<String> iterator = data.iterator();
  29. //由于JDK1.5以后,LinkedList采用了Queue的数据结构,所以遍历时,它从First开始遍历
  30. while(iterator.hasNext()) {
  31. String str = iterator.next();
  32. System.out.println(str);
  33. iterator.remove();
  34. }
  35. //也可以单个单个的移除
  36. data.remove("f");
  37. }
  38. }

2.1.3 Vector,LinkedList和ArrayList 的区别

  1. Arraylist 的底层是数组LinkedList的底层是链表


  1. ArrayList采用数组的方式存储对象,这种方式将对象放在连续的位置中,它有一个很大的缺点就是对它们进行删除或插入操作的时候非常麻烦。例如,如果我们要删除列表中某个元素,那么这个元素之后的其它元素都必须向前挪动。而插入元素的时候,在插入位置之后的所有元素都必须向后挪动。

  2. LinkedList不支持快速随机访问,如果要访问LinkedList中第n个元素,必须从头开始查找,然后跳过前面的n-1个元素。所以访问LinkedList元素时,性能会比较低下。因此,如果列表需要快速存取,但不经常进行元素的插入和删除操作,那么选择ArrayList会好一些;如果需要对列表进行频繁的插入和删除操作,那么就应该选择LinkedList。

  3. Vector 由于使用synchronized,做到了线程同步。但是它的效率低下

  4. Arraylist 没有添加synchronized,所以效率相对较高,但是从数据安全性上来讲,比Vector 低下一些

总结:
Arrylist:底层是数组,适合查询,未使用synchronized,效率高数据安全性低
LinkedList:底层是链表(双向联表),适合增删
Vector:类似于Arraylist,使用了synchronized,同步但效率低