学java的小伙伴们都知道,当我们需要将一些相同结构的个体整合在一起时,就可以考虑使用集合了。集合和数组各有什么特点呢?
集合和数组的相似之处:
都可以储存多个对象,对外作为一个整体存在。
集合和数组的区别:
1、集合可以存储键值对映射关系数据,数组不可以。
2、集合的长度可以动态改变,数组的长度运行时固定不可变。
3、集合存储的数据为引用类型数据,如果集合存储基本类型数据也会自动装箱转为包装类存储到集合。数组可以存储基本类型和引用类型数据。
4、集合支持多种数据存储结构类型,数组不支持。
集合体系如图(来自网络)
Iterator是集合体系的接口, 它又分为Collection和Map。
实现类:
ArrayList:数组实现,查询快,增删慢,轻量级;(线程不安全、效率高)
LinkedList:双向链表实现,增删快,查询慢 (线程不安全、效率高)
Vector:数组实现,重量级 (线程安全、使用少)
List 的常用方法:
void add(int index, Object element) :添加对象element到位置index上
boolean addAll(int index, Collection collection) :在index位置后添加容器collection中所有的元素
Object get(int index) :取出下标为index的位置的元素
int indexOf(Object element) :查找对象element 在List中第一次出现的位置
int lastIndexOf(Object element) :查找对象element 在List中最后出现的位置
Object remove(int index) :删除index位置上的元素
ListIterator listIterator(int startIndex) :返回一个ListIterator 跌代器,开始位置为startIndex
List subList(int fromIndex, int toIndex) :返回一个子列表List ,元素存放为从 fromIndex 到toIndex之前的一个元素
List集合的遍历:
for循环 foreach循环 Iterator迭代器
Set集合
Set是无序的(LinkedHashSet是有序的),也就是插入数据的顺序跟取出的顺序不一样;Set元素不可重复。
实现类:
HashSet:数据结构是哈希表(数组+链表);元素无序且唯一,线程不安全,效率高。
LinkedHashSet:数据结构是哈希表和链表共同实现,链表保证了元素的顺序与存储顺序一致,哈希表保证了元素的唯一性。线程不安全,效率高。
TreeSet:数据结构是二叉查找树(红黑树);去重并排序,所以需要元素对象实现Comparable接口。
HashSet集合判断两个元素相等的标准是:
通过equals方法比较两个对象相等,并且hashCode方法的返回值也相等。
Set集合如何保证元素不可重复?
添加A元素的时,先调用A的hashcode方法,计算出hash值,通过hash值能确定元素该在哪个位置。若有一个已知的存在的元素,先比较的hashcode,如果hashcode相同,那么就接着对比A元素的equals方法在进行比较,如果返回的结果是true,那么就说明A元素和这个已知的元素重复,不进行存储。
HashSet常用的方法:
public boolean contains(Object o) :如果set包含指定元素,返回true
public Iterator iterator()返回set中元素的迭代器
public Object[] toArray() :返回包含set中所有元素的数组public Object[] toArray(Object[] a) :返回包含set中所有元素的数 组,返回数组的运行时类型是指定数组的运行时类型
public boolean add(Object o) :如果set中不存在指定元素,则向set加入
public boolean remove(Object o) :如果set中存在指定元素,则从set中删除
public boolean removeAll(Collection c) :如果set包含指定集合,则从set中删除指定集合的所有元素
public boolean containsAll(Collection c) :如果set包含指定集合的所有元素,返回true。如果指定集合也是一个set,只有是 当前set的子集时,方法返回true
Set集合的遍历: foreach循环 Iterator迭代器
Map
map保存具有映射关系的数据,它没有继承Collection接口。
实现类:
HashTable:数据结构是数组+链表;线程安全,性能最差,修改时会锁住整张表;不可null键 null值;采用链地址法解决哈希冲突。
HashMap:数据结构是数组+链表;线程不安全,性能最好;可一个null键多个null值;采用链地址法解决哈希冲突。
LinkedHashMap:跟HashMap类型,但会维护一个双向链表来保持插入的顺序是有序的。
TreeMap:数据结构是红黑树;对map的key可以进行排序。
ConcurrentHashMap:数组+链表,默认将hash分为16个桶。线程安全,将数据分段存储,每段有一个锁,这样可以允许多 个段的数据被并发访问,读操作不加锁,性能相对较好。
Map常用方法:
Object put(Object key,Object value):用来存放一个键-值对Map中
Object remove(Object key):根据key(键),移除键-值对,并将值返回
void putAll(Map mapping) :将另外一个Map中的元素存入当前的Map中
void clear() :清空当前Map中的元素
Object get(Object key) :根据key(键)取得对应的值
boolean containsKey(Object key) :判断Map中是否存在某键(key)
boolean containsValue(Object value):判断Map中是否存在某值(value)
public Set keySet() :返回所有的键(key),并使用Set容器存放
public Collection values() :返回所有的值(Value),并使用Collection存放
public Set entrySet() :返回一个实现 Map.Entry 接口的元素 Set
map集合的遍历(4种方法):
//方法一:
map.forEach((key, value) -> {
System.out.println("key=" + key + ",value=" + value);
});
//方法二:
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
System.out.println("key:" + entry.getKey() + ",value:" + entry.getValue());
}
//方法三:
//获取所有的 key,根据 key 取出对应的value
for (String key : map.keySet()) {
System.out.println("key:" + key + ",value:" + map.get(key));
}
//方法四
//取出对应的 key,value 键值对,容量大时推荐使用
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("键值对:" + entry);
//获取 键值对的 key
System.out.println("key:" + entry.getKey());
//获取 键值对的 value
System.out.println("value:" + entry.getValue());
}
存储结构 | 顺序 | 唯一 | 查询 | 添加/删除 | |
ArrayList | 顺序表 | 有序添加 | 不唯一 | 索引查询效率高 | 效率低 |
LinkedList | 链表 | 有序添加 | 不唯一 | 效率低 | 效率高 |
HashSet | 哈希表 | 无序 | 唯一 | 效率最高 | 效率最高 |
HashMap | 哈希表 | key无序 | key唯一 | 效率最高 | 效率最高 |
LinkedHashSet | 哈希表+链表 | 有序添加 | 唯一 | 效率最高 | 效率最高 |
LinkedHashMap | 哈希表+链表 | key有序添加 | key唯一 | 效率最高 | 效率最高 |
TreeSet | 二叉树 | 有序(自然) | 唯一 | 效率中等 | 效率中等 |
TreeMap | 二叉树 | 有序(自然) | key唯一 | 效率中等 | 效率中等 |
Collection和Collections的区别:
1.排序操作
Collections提供了一下几个方法用于对List集合进行排序(都是静态的):
·reverse(list):反转集合中的元素
·shuffle(list):对集合中的元素进行随机排序
·sort(list):根据自然顺序对集合中的元素进行排序
·sort(list,comparator):根据定制顺序对集合中的元素进行排序
·swap(list,i,j):将i和j处的元素进行交换
·rotate(list,i):将i和list.length-1-i处的元素进行交换
2. 查找、替换操作
Collections提供了一下几个方法用于对List集合进行查找、替换(都是静态的):
·binarySearch(list,object):查找指定元素在list中的索引,但执行此方法前必须保证list已经处于有序状态。
·max(collection):按照自然排序查找collection中的最大值
·max(collection,comparator):按照定制排序查找collection中的最大值
·min(collection):按照自然排序查找collection中的最小值
·min(collection,comparator): 按照定制排序查找collection中的最小值
·fill(list,object):使用指定元素object替换list中的所有元素
·frequency(colletion,object):返回集合collection中object元素出现的次数
·replaceAll(list,oldval,newval):用新的元素newval替代list中所有旧的元素oldval
3.同步控制
Collections提供了多个synchronizedXxx方法用来同步集合对象,可以解决多线程并发访问集合时的线程安全问题。
4.设置不可变的集合
Collections提供了三个方法返回一个不可变的集合:
·emptyXxx():返回一个空的不可变的集合对象。
·singleton(object):返回一个只包含一个元素object的集合对象。
·unmodifiableXxx(colletion or map):返回一个不可变的视图。