什么是集合
集合存储对象的容器,面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,存储对象,集合是存储对象最常用的一种方式。
集合的出现就是为了持有对象。
为什么需要集合
1. 集合可以存储任意类型的对象数据,数组只能存储同一种数据类型的数据(当然,Object类型的数组除外- -)
2. 集合的长度可以发生变化的,数组的长度是固定的
集合体系
来看一张恐怖的集合体系图- - 瞬间想🐶带有木有
当然,主要需要掌握的是这些
1、Collection
首先看Collection——单例集合的根接口
对于Collection接口中的方法,具体分类如下:
增加
add(E e) ——添加成功返回true,添加失败返回false
addAll(Collection c) ——把一个集合的元素添加到另外一个集合中去。
删除
clear()
remove(Object o)
removeAll(Collection c)
retainAll(Collection c)
查看
size()
判断
isEmpty()
contains(Object o) ——contains方法内部是依赖于equals方法进行比较
containsAll(Collection c)
迭代
toArray()——把集合中的元素全部 存储到一个Object的数组中返回
iterator()——迭代器
迭代器的作用:用于抓取集合中的元素。
迭代器的方法:
hasNext() 询问是否有元素可遍历,如果有元素可以遍历,返回true,否则返回false 。
next() 返回元素
remove() 移除迭代器最后一次返回的元素。
1.1、List接口
看完单例集合的根接口Collection中的方法,接下来看List接口中特有方法
时刻回忆集合体系结构图!!!
再来强制复习一遍
首先,如果是实现了List接口的集合类,该集合类具备的特点:有序,可重复的特点。
也就是所,List接口中特有的方法都存在索引值。只有List接口下面的集合类才具备索引值,其他接口下面的集合类都没有索引值。
List接口中特有方法如下
添加
add(int index, E element)
addAll(int index, Collection c)
获取
get(int index)
indexOf(Object o)
lastIndexOf(Object o)
subList(int fromIndex, int toIndex)
修改
set(int index, E element)
迭代
listIterator()
ListIterator特有的方法:
添加:
hasPrevious()——判断是否存在上一个元素。
previous()——当前指针先向上移动一个单位,然后再取出当前指针指向的元素。
next()——先取出当前指针指向的元素,然后指针向下移动一个单位。
---------------------------
add(E e) 把当前有元素插入到当前指针指向的位置上。
set(E e) 替换迭代器最后一次返回的元素。
下面举一个简单的🌰
使用三种方式遍历集合的元素
第一种: 使用get方法遍历。
第二种: 使用迭代器正序遍历。
第三种: 使用迭代器逆序遍历。
在迭代器迭代元素的过程中,不允许使用集合对象改变集合中的元素个数,如果需要添加或者删除只能使用迭代器的方法进行操作。
如果使用了集合对象改变集合中元素个数那么就会出现ConcurrentModificationException异常。
1.1.1、ArrayList
看完List接口,接下来看List的实现类——ArrayList
记得回过头看体系结构!!!
ArrayList的底层维护了一个Object数组,使用无参构造函数时,Object数组默认的容量是10,当长度不够时,自动增长0.5倍
特点: 查询速度快,增删慢。如果目前的数据是查询比较多,增删比较少的时候,那么就使用ArrayList存储这批数据——比如高校的图书馆
ArrayList 特有的方法如下
ensureCapacity(int minCapaci上ty)
trimToSize()
1.1.2、LinkedList
LinkedList底层是使用了链表数据结构实现的,特点:查询速度慢,增删快。
LinkedList特有的方法
addFirst(E e)——把元素添加到集合的首位置上
addLast(E e)——把元素添加到集合的末尾处
getFirst()
getLast()
removeFirst()
removeLast()
descendingIterator() ——返回逆序的迭代器对象
使用LinkedList实现堆栈数据结构的存储方式。
push()
pop()
使用LinkedList模拟队列数据结构的存储方式。
offer()
poll()
1.1.3、Vector
Vector——底层也是维护了一个Object的数组实现的,实现与ArrayList是一样的,但是Vector是线程安全的,操作效率低。
特有的方法:
void addElement(E obj)——在集合末尾添加元素
EelementAt( int index)——返回指定角标的元素
Enumeration elements()——返回集合中的所有元素,封装到Enumeration对象中
Enumeration接口:
boolean hasMoreElements()——测试此枚举是否包含更多的元素。
E nextElement()——如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
举例:
Vector v = new Vector();
v.addElement("张三");v.addElement("李四");v.addElement("王五");
Enumeration e = v.elements(); //获取迭代器
while(e.hasMoreElements()){
System.out.println(e.nextElement());
}
1.2、Set
Set体系注重独一无二的性质,该体系集合不会存储重复的元素,用于存储无序(存入和取出的顺序不一定相同)元素。
1.2.1、HashSet
HashSet底层是使用了哈希表来支持的,特点:存取速度快。
HashSet的实现原理:
往HashSet添加元素的时候,HashSet会先调用元素的hashCode方法得到元素的哈希值 ,然后通过元素的哈希值经过移位等运算,就可以算出该元素在哈希表中的存储位置。
情况1: 如果算出元素存储的位置目前没有任何元素存储,那么该元素可以直接存储到该位置上。
情况2: 如果算出该元素的存储位置目前已经存在有其他的元素了,那么会调用该元素的equals方法与该位置的元素再比较一次
如果equals返回的是true,那么该元素与这个位置上的元素就视为重复元素,不允许添加。如果equals方法返回的是false,那么该元素允许添加。
1.2.2、TreeSet
TreeSet的特点是:如果元素具备自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储。
TreeSet的注意事项:
1. 往TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储。
2. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,那么该元素所属的类必须要实现Comparable接口,把元素的比较规则定义在compareTo(T o)方法上。
3. 如果比较元素的时候,compareTo方法返回的是0,那么该元素就被视为重复元素,不允许添加。
4. 往TreeSet添加元素的时候, 如果元素本身没有具备自然顺序的特性,而元素所属的类也没有实现Comparable接口,那么必须要在创建TreeSet的时候传入一个比较器。
5. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,而元素所属的类已经实现了Comparable接口, 在创建TreeSet对象的时候也传入了比较器,那么是以比较器的比较规则优先使用。
2、双列集合Map
请先回忆体系结构!!!!
如果是实现了Map接口的集合类,存储的数据都是以键值对的形式存在的,键不可重复,值可以重复。
Map接口的方法:
添加
put(K key, V value)
putAll(Map m)
删除
remove(Object key)——根据键删除一条map中的数据,返回的是该键对应的值
clear()
获取
get(Object key)——根据指定的键获取对应的值
size()——获取map集合键值对个数
判断
containsKey(Object key)
containsValue(Object value)
isEmpty()
迭代
keySet()——把Map集合中的所有键都保存到一个Set类型的集合对象中返回
values()——把所有的值存储到一个Collection集合中返回
entrySet()
2.1、HashMap
HashMap的底层也是基于哈希表实现的
HashMap的存储原理:
往HashMap添加元素的时候,首先会调用键的hashCode方法得到元素的哈希码值,然后经过运算就可以算出该元素在哈希表中的存储位置。
情况1: 如果算出的位置目前没有任何元素存储,那么该元素可以直接添加到哈希表中。
情况2:如果算出的位置目前已经存在其他的元素,那么还会调用该元素的equals方法与这个位置上的元素进行比较
如果equals方法返回的是false,那么该元素允许被存储,如果equals方法返回的是true,那么该元素被视为重复元素,不允存储。
2.2、TreeMap
TreeMap是基于二叉树数据结构实现的,会对元素的键进行排序存储。
TreeMap 要注意的事项:
1. 往TreeMap添加元素的时候,如果元素的键具备自然顺序,那么就会按照键的自然顺序特性进行排序存储。
2. 往TreeMap添加元素的时候,如果元素的键不具备自然顺序特性, 那么键所属的类必须要实现Comparable接口,把键的比较规则定义在CompareTo方法上。
3. 往TreeMap添加元素的时候,如果元素的键不具备自然顺序特性,而且键所属的类也没有实现Comparable接口,那么就必须在创建TreeMap对象的时候传入比较器。
3、Collections
Collections是集合框架中的工具类,该工具类中的方法都是静态的。
Collections:常见方法:
1、对list进行二分查找:
int binarySearch(list,key);
int binarySearch(list,key,Comparator);
2、对list集合进行排序。
sort(list);
sort(list,Comparator);
3、对集合取最大值或者最小值。
max(Collection)
max(Collection,comparator)
min(Collection)
min(Collection,comparator)
4、对list集合进行反转。
reverse(list);
5、对比较方式进行强行逆转。
Comparator reverseOrder();
ComparatorreverseOrder(Comparator);
6、对list集合中的元素进行位置的置换。
swap(list,x,y);
7、对list集合进行元素的替换。如果被替换的元素不存在,那么原集合不变。
replaceAll(list,old,new);