集合框架
- 集合框架:为什么要出现这么多容器?
因为每一个容器对数据的存储方式都有不同。这个存储方式称之为:数据结构。
- 集合类的由来:
对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定。就使用集合容器进行存储。
- 集合特点:
- 用于存储对象的容器。
- 集合的长度是可变的。
- 集合中不可以存储基本数据类型值。
集合容器因为内部的数据结构不同,有多种具体容器。
不断的向上抽取,就形成了集合框架。
接口 Collection
boolean retainAll(Collection<?> c) //取交集
boolean removeAll(Collection<?> c) //删除与c里面元素相同的元素
boolean addAll(Collection<? extends E> c) //取并集
boolean containsAll(Collection<?> c) //如果此 collection 包含指定 collection 中的所有元素,则返回 true。
Iterator iterator()
返回在此 collection 的元素上进行迭代的迭代器。
boolean hasNext() //如果仍有元素可以迭代,则返回 true。
E next()//返回迭代的下一个元素。
void remove()// 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。
for(Iterator it=对象.iterator();it.hasNext();)
it.next();//do something
List
元素是有序的可以重复,因为有索引
- List特有方法(凡是可以操作角标的方法都是List特有方法)
- ListIterator是Iterator的子接口。在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生并发异常。所以在迭代市只能用迭代器方法操作元素,但是Iterator方法是有限的,如果想要添加修改等操作需要使用子接口,ListIterator
注意不能用迭代器的同时使用集合的方法进行操作(并发修改),否则会抛出异常ConcurrentModificationException
ListIterator方法:
void add(E e)
将指定的元素插入列表(可选操作)。
boolean hasNext()
以正向遍历列表时,如果列表迭代器有多个元素,则返回 true(换句话说,如果 next 返回一个元素而不是抛出异常,则返回 true)。
boolean hasPrevious()
如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。
E next()
返回列表中的下一个元素。
int nextIndex()
返回对 next 的后续调用所返回元素的索引。
E previous()
返回列表中的前一个元素。
int previousIndex()
返回对 previous 的后续调用所返回元素的索引。
void remove()
从列表中移除由 next 或 previous 返回的最后一个元素(可选操作)。
void set(E e)
用指定元素替换 next 或 previous 返回的最后一个元素(可选操作)。
void add(int index, E element)//在列表的指定位置插入指定元素(可选操作)。
boolean addAll(Collection<? extends E> c)//添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序
ListIterator<E> listIterator()//返回此列表元素的列表迭代器(按适当顺序)。
List<E> subList(int fromIndex, int toIndex)//返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
E remove(int index)
E set(int index, E element)
E get(int index)
Vector
内部是数组数据结构,是同步的。增删,查询都很慢!
1.2版本之前使用(当时没有集合框架)较多后被ArrayList替代
枚举就是Vector特有的取出方式,枚举和迭代器很像,因为枚举名称方法较长所以被迭代器取代了
ArrayList
内部是数组数据结构,是不同步(异步)的。替代了Vector。查询的速度快。
1.2版本之后出现替代了Vector,默认构造元素长度是10,超出后按50%延长(Vector是100%)。
比较的时候需要注意equals方法的重写。
LinkedList
内部是链表数据结构,是不同步的。增删元素的速度很快。
- 特有方法
- 1.6版本以后的方法
boolean offer(E e)
将指定元素添加到此列表的末尾(最后一个元素)。
boolean offerFirst(E e)
在此列表的开头插入指定的元素。
boolean offerLast(E e)
在此列表末尾插入指定的元素。
E peek()
获取但不移除此列表的头(第一个元素)。
E peekFirst()
获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
E peekLast()
获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。
E poll()
获取并移除此列表的头(第一个元素)
E pollFirst()
获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
E pollLast()
获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
Set
元素是无序的,不可以重复
Set集合的功能和Collection功能是一致的
HashSet
数据结构是哈希表,线程是非同步的
哈希表储存方式:先判断地址值(hashCode)是否一样,不一样就存入,一样的话继续判断是否同一个对象(equals方法),不是同一对象的话会在同地址下顺延。
哈希表确定元素是否相同
1. 判断的是两个元素的哈希值是否相同。如果相同,在判断两个对象的内容是否相同。
2. 判断哈希值相同,其实判断的是对象的hashCode的方法。判断内容相同,用的是equals方法。
注意:如果哈希值不同,是不需要判断equals。
TreeSet
可以对Set集合中的元素进行排序
自定义数据类型时需要重写Compareble里的compareTo函数
int compareTo(T o) //比较此对象与指定对象的顺序。
底层数据结构是二叉树,保证元素唯一性的依据compareTo方法return0.
treeSet排序的第一种方式:让让元素自身具备比较性,元素需要实现CompareTo方法。这种顺序叫做自然顺序也叫默认顺序
TreeSet排序的第二种方式:让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。将该类对象作为参数传递给TreeSet集合的构造函数。
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetTest {
public class ComparatorByLength implements Comparator {
@Override
public int compare(Object o1, Object o2) {
String s1 = (String)o1;
String s2 = (String)o2;
int temp = s1.length()-s2.length();
return temp==0? s1.compareTo(s2): temp;
//基础类型都有compareTo方法
}
}
public static void main(String[] args) {
TreeSet ts = new TreeSet(new ComparatorByLength());
ts.add("aaaaa");
ts.add("zz");
ts.add("nbaq");
ts.add("cba");
ts.add("abc");
Iterator it = ts.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}