Java集合说实话,我觉得挺烦的,各种类型的集合各种特点,现在我就在来总结一下集合。
集合框架图:
一.集合的由来
通常,我们在开发程序时,并不知道在程序中需要创建多少个对象
的对象,我们要用什么来存放这些对象呢?数组的长度是固定的,并且只能存放一种类型的数据,灵活性太低,所以集合
应运而生。
二.集合是什么
注意:1)java集合只能用于存放对象,就算往里面存放了一个int 类型的数据,在存放的时候也会自动包装成
Integer类型。每一种基本数据类型都对应了它们的对象包装类。
2)java集合中存放的是对象的引用,真正的对象仍然是存放于虚拟机堆中。
3)集合存放的对象是不限数量,不限类型的。同一个集合中,可以存放多个不同类型的对象。
三.集合特点
要是hashNext(),next(),remove()三种方法。它的一个子接口ListIterator在它的基础上又增加了3种方法,分别是
hasPrevious()previous(),add()方法。接口是可以继承的,并且一个接口可以继承多个接口。也就是说如果实现 Iterator
接口,那么在遍历集合的时候,只能从前往后遍历,被遍历到的的元素,不能够被再次遍历,通常无序集合实现的
都是这个接口,例如HashSet。如果实现的是 LinkedIterator接口,那么该集合就能够双向遍历,既可以通过next()
方法向后遍历,也可以通过previous()向前遍历,通常有序集合实现该接口,例如ArrayList。在开发的时候,我们
只需要根据需求,来确定要使用哪一个实现类。
四.集合详解
Iterator:存在于java.util包中,主要方法有hasNext(),next(),remove()。代码实例:
package com.java.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListText {
public static void main(String[] args) {
//创建一个List集合
List list=new ArrayList();
list.add("1");
list.add("2");
list.add("3");
//得到list集合的绑定迭代器
Iterator it = list.iterator();
//遍历元素
while(it.hasNext()) {
Object obj = it.next();
System.out.println(obj);
}
}
}
2)Conllection:List接口和Set接口的父接口。
3)List:有序,可以重复的集合。
List接口的3个典型实现:
(1)List list=new ArrayList();
底层数据结构是数组,查询快,增删慢,线程不安全,效率高。
(2)List list =new Vector();
底层数据结构的数组,查询快,增删慢,线程安全,效率低,几乎已经淘汰了这个集合。
(3)List list=new LinkedList();
底层数据结构的链表,查询慢,增删快,线程不安全,效率高。
我们可以这么记,底层数据结构是数组,查询可以直接按角标进行查询,所以快。但是如果增删元素,会影
响到后面元素的角标所以慢。底层数据结构是链表时,查询要一个一个的查,所以慢。但是如果增删元素,不会影响
到后面元素的角标,所以快。(数组就像身上编了号站成一排的人,要找第10个人很容易,根据人身上的编号很快就
能找到。但插入、删除慢,要望某个位置插入或删除一个人时,后面的人身上的编号都要变。当然,加入或删除的人
始终末尾的也快。链表就像手牵着手站成一圈的人,要找第10个人不容易,必须从第一个人一个个数过去。但插入、
删除快。插入时只要解开两个人的手,并重新牵上新加进来的人的手就可以。删除一样的道理。)
除此之外,List接口可以使用普通for()循环来遍历,还可在指定位置增加元素和替换元素。代码如下:
package com.java.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListText {
public static void main(String[] args) {
//创建一个List集合
List list=new ArrayList();
list.add("1");
list.add("2");
list.add("3");
//获得指定对象的索引
int j=list.indexOf("3");
System.out.println("索引为:"+j);
//利用for循环来遍历集合
for(int i=0;i<list.size();i++) {
System.out.println(list.get(i));
}
//插入元素和替换元素
list.set(1,"3");
list.add(3,"4");
//得到list集合的绑定迭代器
Iterator it = list.iterator();
//遍历元素
while(it.hasNext()) {
Object obj = it.next();
System.out.println(obj);
}
}
}
4)Set接口:典型是HashSet,是一个无序,不可重复的集合。
Set set=new HashSet();
不能保证元素的顺序,不可重复,不是线程安全的。集合元素可以为NULL。底层实现其实是一个数组,
存在的意义是加快查询速度。我们知道在一般的数组中,元素在数组中的索引位置是随机的,元素的取值和元素的位置
由不确定的关系,因此,在数组中查找特定的元素时,需要把查找值和一系列的元素进行比较,此时的查询效率取决
于查询次数。而HashSet集合底层数组的索引和值有一个确定的关系:index=Hash(value)。那么只需要调用这个公式,
就能够快速的找到索隐或元素。
对于HashSet集合,如果两个对象的equals()方法返回的是true,那么这两个对象的HashCode也应该相同。
当向HashSet集合中存放元素时,HashSet会先调用该对象的hashCode()方法来得到该对象的hashCode值,
然后根据hashCode值来决定该对象在集合中的位置。如果hashCode值不同,直接把元素指定到hashCode相应的位
置。如果hashCode相同,那么会继续使该元素和集合元素进行equals()方法比较,如果返回值为true,则视为是一
个对象,不保存在HashSet集合中。
注意:每一个存储到 哈希 表中的对象,都得提供 hashCode() 和 equals() 方法的实现,用来判断是否是同一个
对象对于 HashSet 集合,我们要保证如果两个对象通过 equals() 方法返回 true,这两个对象的 hashCode 值也应该相同。