Java开发之集合框架
集合框架的概念:
集合代表了一组对象(和数组一样,但数组长度不能变,而集合能)。Java中的集合框架定义了一套规范,用来表示、操作集合,使具体操作与实现细节解耦。
集合框架的两大基类Collection与Map
Collection:表示一组纯数据。
Map:表示key-value的键值对。
Collection接口介绍
collection继承关系图如图所示:collection有三个接口:
Set:表示不允许有重复元素的集合。
List:表示允许有重复元素的集合。
Queue:JDK1.5新增,与上面两个集合类主要是的区分在于Queue主要用于存储数据,而不是处理数据。
collection的方法
add() //添加元素 返回值为boolean
注:因为List的集合中允许添加重复的元素所有返回的boolean全部为true。Set集合当存储重复就会返回false
remove() //删除指定元素 返回值为boolean
clear() //清空集合 返回值为boolean
contains() //判断是否包含 返回值为boolean
isEmpty() //判断是否为空 返回值为boolean
size() //获取元素的个数 返回值为int
addAll() //集合的元素添加到另一个集合 返回值为boolean
removeAll() //删除的是交集 返回值为boolean
containsAll() //判断调用的集合是否包含传人的集合 返回值为boolean
retainAll() //取交集 返回值为boolean 注: 如果调用的集合改变就返回true 如果调用集合不改变返回false遍历(使用迭代迭代器)
(一)
Collection c=newArrayList();
c.add(newStudent("zhang",2));
c.add(newStudent("312",23));
c.add(newStudent("sdfas",221));
Iterator it=c.iterator(); // iterator() 获取迭代器
while(it.hasNext()){ // hasNext()判断集合中是否有元素有就返回true
System.out.println(it.next()) // next()返回迭代的下一个元素。
;}(二)
for(元素数据类型 变量:集合) {
}(三)
for(int i= 0;i<list.size();i++){
}
}
list接口介绍
List接口扩展自Collection,它可以定义一个允许重复和有序集合(存和取的顺序是一致的),List接口增加了一个能够双向遍历线性表的新列表迭代器ListIterator。AbstractList类提供了List接口的部分实现,AbstractSequentialList扩展自AbstractList,主要是提供对链表的支持。下面来介绍List的实现类。
list接口特有的方法
void add(int index, E element);//在指定位置添加元素 index <=size并且大于index>=0都不会报异常
注:当存储时使用不存在的索引时就会出现 IndexOutOfBoundsException
E remove(int index); //通过索引删除元素 将被删除的元素返回
注:删除的时候不会自动装箱
E get(int index); //通过索引获取元素
E set(int index, E element); ///将指定位置的元素修改遍历(通过get()方法)
(一)
for(int i= 0;i<list.size();i++){
System.out.println(list.get(i));
}
(二)
ListIterator lit=list.listIterator();//获取迭代器
while(lit.hasNext()){
lit.add();//遍历的时候增加元素并发修改
}
while(lit.hasPrevious()){ //获取元素并将指针向前移动}
ArrayList实现类
ArrayList底层使用数组实现的,它是用数组存储元素的,这个数组可以动态创建,如果元素个数超过了数组的容量,那么就创建一个更大的新数组扩容大小为前一个数组的50%,并将当前数组中的所有元素都复制到新数组中。它的特点是增删慢,查找快。
LinkedList实现类
LinkedList是在一个链表中存储元素。链表和数组的最大区别在于它们对元素的存储方式的不同导致它们在对数据进行不同操作时的效率不同,同样,ArrayList与LinkedList也是如此,实际使用中我们需要根据特定的需求选用合适的类。它的特点是增删快,查找慢。
public void addFirst(Ee) //在头部添加元素
public void addLast(Ee) //在尾部添加元素
public E getFirst() //获得第一个元素
public E getLast() //获得最后一个元素
publicE removeLast() //删除最后一个元素
publicE removeFirst()
Vector实现类
Vector类实现了一个动态数组。和ArrayList和相似。Vector是同步访问的,保证线程安全。它的特点是增删慢,查找快。
v.addElement(); //添加元素
Enumeration en=v.elements(); //获取枚举
while(en.hasMoreElements()){ //�判决集合中是否有元素
en.nextElement(); //获取集合中的元素
}
Set接口
Set接口扩展自Collection,无序(存和取的顺序不一致),无索引不可以存储重复。HashSet、TreeSet和LinkedHashSet是Set接口的实现类。
HashSet
HashSet以哈希表的形式存放元素,插入删除速度很快。它不允许出现重复元素;不能保证集合中元素的顺序。
1.HashSet原理
我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率, 降低了使用equals()方法的次数
当HashSet调用add()方法存储对象的时候, 先调用对象的hashCode()方法得到一个哈希值, 然后在集合中查找是否有哈希值相同的对象,如果没有哈希值相同的对象就直接存入集合, 如果有哈希值相同的对象, 就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入, true则不存2.将自定义类的对象存入HashSet去重复
类中必须重写hashCode()和equals()方法
hashCode(): 属性相同的对象返回值必须相同, 属性不同的返回值尽量不同(提高效率)
equals(): 属性相同返回true, 属性不同返回false,返回false的时候存储
TreeSet
TreeSet : 可以实现排序等功能的集合,它在讲对象元素添加到集合中时会自动按照某种比较规则将其插入到有序的对象序列中,并保证该集合元素组成按照一定顺序排列。
TreeSet集合之所也能经行排序必须实现Comparable接口 重写compareTo方法
当compareTo方法返回0的时候集合中只有一个元素
当compareTo方法返回正数的时候集合中怎么存就怎么取
当compareTo方法返回0的时候集合中集合会倒序存储因为TreeSet底层实现是二叉树:
小的存储在左边(负数),大的存储在右边(正数),相等就不存
compareTo方法,在TreeSet集合如何存储元素取决于compareTo方法的返回值TreeSet(Comparator<? super E> comparator) 构造方法需要传comparator来经行比较
LinkedHashSet
LinkedHashSet集合是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
Map
Map接口关系继承图Map是一个双列集合,是Key-Value具有映射关系的数据 下面我会一一说明Map的实现类
Map集合的方法
* a:添加功能
V put(K key,V value):添加元素。
如果键是第一次存储,就直接存储元素,返回null 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值* b:删除功能
void clear():移除所有的键值对元素
V remove(Object key):根据键删除键值对元素,并把值返回* c:判断功能
boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空* d:获取功能
Set> entrySet():
V get(Object key):根据键获取值
Set keySet():获取集合中所有键的集合
Collection values():获取集合中所有值的集合e:长度功能
int size():返回集合中的键值对的个数遍历
第一种方法
//获取所有的键
Set set=map.keySet(); //获取集合中所有键的集合
Iterator it=set.iterator(); //获取迭代器
while(it.hasNext()){ //判断是否有元素
map.get(it.next()); //获取集合中所有键的集合
}第二种方法
for(String string : map.keySet()) {
System.out.println(string+map.get(string));
}第三种方法
//Map.Entry说明Entry是Map的内部接口 将建和值封装成Entry对象,存储在set集合中
Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
//获取每一个对象
Iterator<Map.Entry<String,Iterator> it= entrySet.iterator();
while(it.hasNext()){
//获取每一个entry对象
Map.Entry en=it.next();
String key=en.getKey();//根据键值对对象获取键
Integer value=en.getValue();//根据键值对对象获取值
System.out.println(key+"="+value);
}第四种方法
for(Map.Entry en : map.entrySet() ) {
System.out.println(en.getKey()+en.getValue());
}
HashMap
底层是哈希表数据结构,允许使用 null 值和 null 键,该集合是不同步的。HashMap是JDK1.2版本出现的,线程不安全,效率高。
注:如果键是自定义类型为键需要重写hashCode()和equals()方法来保证键的唯一
TreeMap
底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。
注:如果键是自定义类型需要实现Comparable接口 重写compareTo方法来保证键的唯一
TreeMap(comparator<? super K> comparator) 构造方法需要传comparator来经行比较
LinkedHashMap
LinkedHashMap保证键的唯一同事保证怎么存怎么取出来
Hashtable
Hashtable不可以储存null键和null值,是JDK1.0版本出现的,线程安全。