一、集合是什么?

Java集合类是一个用来存放对象的容器,它存放于 java.util 包中,其中每一个对象叫元素。

注意:①、集合只能存放对象。比如你存一个 int 型数据 1放入集合中,其实它是自动转换成 Integer 类后存入的,Java中每一种基本类型都有对应的引用类型。

集合存放的是多个对象的引用,对象本身还是放在堆内存中。

   ③、集合可以存放不同类型,不限数量的数据类型。

二、Java 集合框架图

java最全的集合类图 java集合图解_List

 三、集合详解

  从上图可以看到Map接口和Collection接口是所有集合框架的父接口,Java常用的集合包括List,Set,以及Map。而List,Set和Map都是接口,其中List接口,Set接口是继承了Collection接口,而Map接口是没有继承Collection接口,因为List和Set集合一般放的单个对象,Map放的是键值对,也就是成对的两个对象,键值对就是可以根据一个键值获得对应的一个值,因为Collection不具备这种特点,所以Map并没有继承Collection。

1.先谈谈接口:Collection

Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements),我们看一下Collection接口的使用:

1         //我们这里将 ArrayList集合作为 Collection 的实现类
 2         Collection collection = new ArrayList();
 3         
 4         //添加元素
 5         collection.add("AA");
 6         collection.add("BB");
 7         collection.add("CC");
 8 
 9        //检测是否存在某个元素
10         collection.contains("AA");
11 
12         //删除指定元素
13         collection.remove("AA");
14 
15         //判断是否为空
16         collection.isEmpty();
17 
18         //删除所有元素
19         Collection del = new ArrayList();
20         del .add("CC");
21         collection.removeAll(del );
22                                
23         //利用增强for循环遍历集合
24         for(Object obj : collection){
25             System.out.println(obj);
26         }
27         //利用迭代器 Iterator
28         Iterator iterator = collection.iterator();
29         while(iterator.hasNext()){
30             Object obj = iterator.next();
31             System.out.println(obj);
32         }

代码中谈到了Iterator,就先说一下Iterator

(1)Iterator:迭代器,它可以说是Collection分支集合的顶层接口,它的内部封装了三个方法,用来遍历集合:

next():返回迭代器刚越过的元素的引用,返回值是 Object,需要强制转换成自己需要的类型

  hasNext():判断容器内是否还有可供访问的元素

  remove():删除迭代器刚越过的元素

1      //构造 List 的迭代器
2         Iterator it = list.iterator();
3         //通过迭代器遍历元素
4         while(it.hasNext()){        //list中是否存在下一个对象
5             Object obj = it.next(); //遍历,并赋值给对象
6             System.out.println(obj);//输出
7         }

 下面来说一下Collection接口下面的list接口和set接口

(2)List集合:有序可重复(顺序是按照放入的顺序排列的,可重复指的是可以放入一样的元素)

List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等,现在分别说一下它们的实现:

  ①ArrayList :List list1 = new ArrayList();

  底层:使用数组实现 。

  特点:查找效率高,随机访问效率高,增删效率低,非线程安全的。

  代码:实现Arrarylist的基本操作。 

1 //生成arrayList实例对象    
 2  List arrayList= new ArrayList();
 3 
 4 //ArrayList的添加:  
 5   arrayList.add("a"); //在末尾添加元素   
 6   arrayList.add("b");  
 7   arrayList.add("c");  
 8   arrayList.add("d");  
 9   arrayList.add("e");  
10   arrayList.add(2,"f");//在指定位置插入元素  
11 
12 //ArrayList的删除  
13   arrayList.remove(2);//移除下标为2的元素  
14 
15 //ArrayList的修改  
16   arrayList.set(0,"a");//把下标为1的元素修改为元素"a"  
17 
18 //ArrayList的查询,这里需要遍历ArrayList  
19 //普通for语句遍历  
20 for(int i=0;i<arrayList.size();i++){  
21   System.out.println(list.get(i));
22 }   
23 
24 //迭代器方式:  
25  //构造 List 的迭代器
26 Iterator intertor= list.iterator();
27 while(intertor.hasNext()){  
28    Object obj = it.next();
29    System.out.println(obj);
30 }

②LinkedList:List list2 = new LinkedList()

  底层:使用双向循环链表实现。 
  特点:查找效率低,随机访问效率低,增删效率高,非线程安全的 
  代码:与实现Arrarylist的基本操作基本一致,此处已不再声明。

  ③Vector:List list3 = new Vector();

  底层:底层数据结构是数组。 
  特点:查询快,增删慢;线程安全,效率低(Vector是线程安全,因为是线程安全的,所以效率上比ArrayList要低)

  代码:与实现Arrarylist的基本操作基本一致。

1  List list = new Vector();
 2         list.add("A");
 3         list.add("B");
 4         list.add("C");
 5 
 6         list.remove("A");
 7         list.set(0,"修改");
 8 
 9         list.add(2,"新增");
10 
11         for(Object obj:list)
12         {
13             System.out.println(obj);
14         }
15 
16         Iterator iterator = list.iterator();
17         while(iterator.hasNext()){
18             Object obj = iterator.next();
19             System.out.println(obj);
20         }

   ④Stack:就是我们常说到的栈

  底层:Stack实际上也是通过数组去实现的。

  继承:Stack继承于Vector,意味着Vector拥有的属性和功能,Stack都拥有。

  方法:empty(),peek(),pop(),push(E object),search(Object o);下面通过实际的例子来描述一下: 

1 Stack stack = new Stack();
 2         //添加
 3         stack.push("A");
 4         stack.push("B");
 5         stack.push("C");
 6         stack.push("D");
 7 
 8         //查找“A”在栈中的位置
 9         int pos = stack.search("A");
10         System.out.println("the postion of A is:"+pos);
11 
12         // pop栈顶元素,取出栈顶元素,并将该元素从栈中删除
13         stack.pop();
14 
15         // peek栈顶元素,取出栈顶元素,不执行删除
16         String val = (String)stack.peek();
17         System.out.println("peek:"+val);
18 
19         
20         // 遍历并打印出该栈
21         Iterator iterator = stack.iterator();
22         while (iterator.hasNext()){
23             Object obj = iterator.next();
24             System.out.println(obj);
25         }

对于List中的集合的几种特点怎么来记呢?无非底层就是数组和链表两种,可以这样来记:

 数组就像身上编了号站成一排的人,要找第10个人很容易,根据人身上的编号很快就能找到。但插入、删除慢,要望某个位置插入或删除一个人时,后面的人身上的编号都要变。当然,加入或删除的人始终末尾的也快。

  链表就像手牵着手站成一圈的人,要找第10个人不容易,必须从第一个人一个个数过去。但插入、删除快。插入时只要解开两个人的手,并重新牵上新加进来的人的手就可以。删除一样的道理。

(3)Set集合:无序不可重复

Set接口的实现类主要有:hashSet、treeSet 、linkedHashSet

① hashSet:Set hashSet = new HashSet();

  底层:使用哈希表实现 

  特点:不能保证元素的顺序;不可重复;不是线程安全的;集合元素可以为 NULL;判断重不重复,是通过对象本身的hashCode()方法和equals()方法决定的,下图可以详细理解元素是否重复。

 

java最全的集合类图 java集合图解_迭代器_02

方法:下面通过例子来了解一下

1      Set hashset = new HashSet();
 2         //增
 3         hashset.add("A");
 4         hashset.add("B");
 5         hashset.add("C");
 6         //删除
 7         hashset.remove("A");
 8         System.out.println(hashset.contains("A"));
 9         //查
10         for(Object obj:hashset)
11         {
12             System.out.println(obj);
13         }
14 
15         Iterator iterator = hashset.iterator();
16         while(iterator.hasNext()){
17             Object obj = iterator.next();
18             System.out.println(obj);
19         }

  ②treeSet :Set treeSet = new TreeSet();

  底层:使用红黑树算法,擅长于范围查询

  特点:有序;不可重复

  实现:

1         TreeSet set = new TreeSet();
 2         set.add("aaa");
 3         set.add("aaa");
 4         set.add("bbb");
 5         set.add("eee");
 6         set.add("ddd");
 7         set.add("ccc");
 8         //正序遍历
 9         Iterator iterator = set.iterator();
10         while(iterator.hasNext()){
11             Object obj = iterator.next();
12             System.out.println(obj);
13         }
14         //逆序遍历
15         Iterator iterator1 = set.descendingIterator();
16         while(iterator1.hasNext()){
17             Object obj = iterator1.next();
18             System.out.println(obj);
19         }

  ③linkedHashSet :Set linkedHashSet = new LinkedHashSet() 

  底层:底层采用 链表 和 哈希表

  特点:有序;不可重复

下面我们说一下三个set接口实现类的异同:

相同点:都不允许元素重复,都不是线程安全的类,解决办法:Set set = Collections.synchronizedSet(set 对象)

不同点:

  HashSet:不保证元素的添加顺序,底层采用 哈希表算法,查询效率高。判断两个元素是否相等,equals() 方法返回 true,hashCode() 值相等。即要求存入 HashSet 中的元素要覆盖 equals() 方法和 hashCode()方法

  LinkedHashSet:HashSet 的子类,底层采用了哈希表算法以及链表算法,既保证了元素的添加顺序,也保证了查询效率。但是整体性能要低于 HashSet    

  TreeSet:不保证元素的添加顺序,但是会对集合中的元素进行排序。底层采用 红-黑 树算法(树结构比较适合范围查询)