集合框架是为表示和操作多个对象而规定的一种统一的标准体系结构
任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。
接口:即表示集合的抽象数据类型,接口提供了让我们对集合中所表示的内容进行单独操作的可能
实现: 也就是集合框架中接口的具体实现。实际它们就是那些可复用的数据结构。
算法:在一个实现了某个集合框架中的接口的对象身上完成某种有用的计算方法,如查找、排序等
集合是Java API所提供的一系列类,可以用于动态存放多个对象——集合只能存对象 例如:存一个 int 型数据 1放入集合中,其实它是自动转换成 Integer 类后存入的,Java中每一种基本类型都有对应的引用类型。
jdk 1.5开始,集合全部用泛型进行的重写,是一种数据安全的用法
Java的集合框架 从整体上可以分为两种:
1、Collection接口:该接口下的所有子孙均存储的是单一对象
2、Map接口 :该接口下的所有子孙均存储的是key-value(键值对)形式的数据
另外还有三个分支,均是为上述服务的。
Iterator(迭代器):主要用于遍历Colleciton接口的及其子类而设计。
Comparator(比较器): 在集合中存储对象时候,用于对象之间的比较
Collecitons 是工具类:注意该类名带个s,一般就表示工具类。里面提供了N多静态方法,来对Colleciton集合进行操作。
1、数组声明了它容纳的元素的类型,而集合不声明。这是由于集合以object形式来存储它们的元素。
2、一个数组实例具有固定的大小,不能伸缩。集合则使用初始容量和加载因子根据需要动态改变自己的大小。
3、集合中不能放基本数据类型,但可以放基本数据类型的包装类。
Conllection接口是一中允许重复的对象,蒂尼了存取对象的方法。
接口不能被实例化,所以创建集合对象,只能创建其接口的实现类。如:
Collection c1 = new ArrayList();
Collection c2 = new LinkedList();
Collection c3 = new HashSet();
Collection中常用的方法:
方法名 | 描述 |
---|---|
int size(); | 返回此collection中的元素个数。 |
boolean isEmpty(); | 判断此collection中是否包含元素。 |
boolean contains(Object obj); | 判断此collection是否包含指定(equals为true)的元素。 |
boolean containsAll(Collection c); | 判断此collection是否包含指定 Collection c 中的所有元素。比较方式通过 equals比较 |
boolean add(Object element); | 向此collection中添加元素。 |
boolean addAll(Collection c); | 将指定collection中的所有元素添加到此collection中 |
boolean remove(Object element); | 从此collection中移除指定的元素,如果有多个对象重复,则只会删除第一个。 |
boolean removeAll(Collection c); | 移除此collection中那些也包含在指定 Collection c 中的所有元素。比较方式通过 equals比较 |
void clear(); | 移除些collection中所有的元素。 |
boolean retainAll(Collection c); | 仅保留此collection中那些也包含在指定 Collection c 的元素。比较方式通过 equals比较 |
Iterator iterator(); | 返回在此collection的元素上进行迭代的迭代器。 |
Object[] toArray(); | 把此collection转成数组。 |
由于集合中存有很多元素,很多时候需要遍历集合中的所有元素,java专门为集合提供了遍历集合的API:迭代器接口Iterator对象称作迭代器,用以方便的实现对集合内元素的遍历操作。
Iterator是专门的迭代输出接口。所谓的迭代输出就是将元素进行判断,判断是否有内容,如果有内容则把内容取出。
1、 使用集合的方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
2、使用next()获得序列中的下一个元素。
3、 使用hasNext()检查序列中是否还有元素。
4、使用remove()将迭代器新返回的元素删除。
Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。
调用集合对象的iterator()方法,可以获得一个与该集合对象关联的迭代器对象。
List<String> list = new ArrayList<>();
list.add("java基础");
list.add("java高编");
//获得Iterator对象
Iterator<String> iterator = list.iterator();
Iterator定义如下三个方法:
1、boolean hasNext(); //判断游标右边是否有元素。如果有返回true,否则false
2、Object next() ; //返回游标右边的元素并将游标移动到下一个位置
3、void remove(); //删除游标左面的元素(即next的时候跳过的对象)
注意:
1、迭代方向是单向的,只能从前朝后(Iterator有个专为list集合设计的子接口ListIterator可以实现双向迭代)
2、在用迭代器遍历集合的时候,如果要删除集合中的元素,只能调用迭代器的remove(),禁止调用集合对象的remove()方法,否则有可能会出现异常:java.util.ConcurrentModificationException。//并发访问异常
3、 使用ListIterator就可以解决这种异常
public class Test {
public static void main(String[] args) {
List list = new ArrayList<>();
list.add("java基础");
list.add("java高编");
list.add("Android基础");
list.add("Android进阶");
ListIterator it = list.listIterator();
while (it.hasNext()) {
String str = it.next();
if (str.equals("java高编")) {
it.add("MySql");
}
System.out.println(str);
}
System.out.println(list);
}
}
1、实现List接口的集合类中的元素是有序的,且允许重复。
2、List集合中的元素都对应一个整数型的序号记载其在集合中的位置(每个元素都有索引),可以根据序号存取集合中的元素。
3、List集合不仅支持Iterator还支持List集合专用迭代器ListIterator(双向迭代器)
4、List接口比Collection接口中新增的几个实用方法:
public E get(int index);返回列表中的指定位置的的元素
public void add(int index, E element); 在列表的指定位置插入指定元素。将当前处于该位置的元素(如果有的话)和所有后续元素向右移动。
public E set(int index, E element) ; 用指定元素替换列表中指定位置的元素
public E remove(int index) 移除列表中指定位置的元素
public ListIterator listIterator() 返回此列表元素的列表迭代器(List专有)
注意:list集合中的元素的索引与数组中元素的索引一样,均是从0开始。
ArrayList是使用数组结构实现的List集合
优点:对于使用索引取出元素有较好的效率【随机读取效率非常高】,可以使用索引来快速定位对象。缺点:删除和添加效率较低
LinkedList是List的实现类,他是一个基于链表实现的List类,对于顺序访问集合中的元素进行了优化。特别是插入,删除元素的速度特别快。LinkedList即实现了List接口,也实现了Deque接口。因此可以作为栈来使用
优点:删除和添加效率较高
缺点:随机读取效率较低
public void addFirst(E e);向集合头部添加数据
public void addLast(E e);向集合尾部添加数据
public E removeFirst();删除链表第一个数据,并返回被删除的数据
public E removeLast();删除链表的最后一个数据,并返回被删除的数据
对比ArrayList 和LinkedList的效率:
public class Test02 {
public static void main(String[] args) {
long a =System.currentTimeMillis();
LinkedList linkedList = new LinkedList<>();
for (int i = 0 ; i < 99999 ; i++){
linkedList.add("张三:" + i);
}
long b = System.currentTimeMillis();
System.out.println("LinkedList 添加时间:" + (b - a));
ArrayList arrayList = new ArrayList();
for (int i = 0; i < 99999; i++) {
arrayList.add("张三" + i);
}
long c = System.currentTimeMillis();
System.out.println("ArrayList 添加时间:" + (c - b));
for (int i = 0; i < arrayList.size(); i++) {
arrayList.get(i);
}
long d= System.currentTimeMillis();
System.out.println("ArrayList 遍历时间:" + (d - c));
for (int i = 0; i < linkedList.size(); i++) {
linkedList.get(i);
}
long e = System.currentTimeMillis();
System.out.println("linkedList 遍历时间:" + (e - d));
while (linkedList.size() > 0) {
linkedList.removeFirst();
}
long f = System.currentTimeMillis();
System.out.println("linkedList 删除时间:" + (f - e));
while (arrayList.size() > 0){
arrayList.remove(0);
}
long g = System.currentTimeMillis();
System.out.println("arrayList 删除时间:" + (g - f));
}
}
当然,List接口还有几种,这里就不一一介绍了,因为并不常用,作为了解
还有:Vector、Stack 有兴趣可以去了解一下
1、实现Map接口的集合类用来存储“键-值”映射对。key-value
2、Map实现类中存储的“键-值”映射对是通过键来唯一标识,Map底层的“键”是用Set来存放的。即:key 不可重复。
3、映射Map每个元素含有两个部分:名称(key)和值(value)。其中key不得重复,所以它可以组成一个Set,而value部分可以重复可以组成一个Collection。
4、常用的实现子类: HashMap、LinkedHashMap
方法名 | 描述 |
---|---|
Object put(Object key, Object value); | 将指定的“键-值”对存入Map中,返回已经存在的key的Values。如果不存在则返回null。 |
Object get(Object key); | 返回指定键所映射的值 |
Object remove(Object key); | 根据指定的键把此“键-值”对从Map中移除。 |
boolean containsKey(Object key); | 判断此Map是否包含指定键的“键-值”对。 |
boolean containsValue(Object value); | 判断此Map是否包含指定值的“键-值”对。 |
boolean isEmpty(); | 判断此Map中是否有元素。 |
int size(); | 获得些Map中“键-值”对的数量。 |
void clear(); | 清空Map中的所有“键-值”对。 |
Set keySet(); | 返回此Map中包含的键的Set集。 |
Collection values(); | 返回此Map中包含的值的Collection集。 |
HashMap
使用频率最高的一种Map集合。
HashMap内部对“键”用Set进行散列存放。所以根据“键”去取“值”的效率很高。
Map.Entry是Map中内部定义的一个接口,专门用来保存key-value的内容。
可以通过map集合的entrySet()方法来获得所有的Map.Entry组成的set集合。
Map<String, Integer> map = new HashMap<String,Integer>();
Set<Entry<String, Integer>> entrySet = map.entrySet();
Iterator<Entry<String, Integer>> iterator = entrySet.iterator();
Entry<String, Integer> entry = iterator.next();
Integer value = entry.getValue();//获取值
String key = entry.getKey();//获取键