Java集合
集合分为两类:
- 以Collection及其子类为代表的的单个元素存储集合,称为Collection体系
- 以Map及其子类为代表的的键值对存储集合,称为Map体系
特点:
- List:存储元素有序(输入顺序);存储元素可重复
- Set:存储元素无序(输入顺序);存储元素不可重复
- Map:以键值对为存储结构。
ArrayList:以数组为底层基础。
LinkedList:以链表为底层基础。
Vector:以数组为底层基础,线程安全(因为sygnoized关键字的存在)
HashSet:是以Hash表为底层基础,算法通过hashmap进行底层实现的,作为hashmap中的key存在。
SortedSet;TreeSet:是进行排序存在的(从小到大进行存储),以二叉树为底层基础
Hashmap:以哈希表为底层基础,通过key和value对应实现,key键不能重复。
HashTable:安全的,其他同hashmap。
TreeMap:是进行排序存在的(从小到大进行存储),以二叉树为底层基础,通过key和value对应实现,key键不能重复。
1. Collection
存储的元素类型
没有使用“泛型”之前,Collection中可以存储Object的所有子类型。
使用“泛型”之后,Collection中只能存储某个具体的类型。
集合中不能直接存储基本数据类型,需要转换为包装类型才可以。集合中存储的不是对象,而是java对象的内存地址。
Collection c = new ArrayList();没有使用泛型,能够存储Object所有子类型
Collection
常用方法
- boolean add(Object e):向集合中添加元素
- void clear():清除集合
- boolean contains(Object e):判断集合中是否包含此元素,底层调用了equals方法(注意元素是否重写equals方法)。
- boolean isEmpty():判断集合是否为空
- boolean remove(Object e):移除元素,底层调用的equals方法(注意元素是否重写equals方法)。
- int size():获得集合中元素个数
- Object[] toArray():将集合转换为数组
2.迭代器Interator
所有的Collection都能够使用迭代器。
创建迭代器:
- Interator i= c.Interator();
- Interator
i= c.Interator();
迭代器的常用方法:
- hasNext():判断是否具有下一个元素
- Next():获取下一个元素
- Next
3.List集合
存储元素特点:有序且可重复
常用方法:
- void add(int index,Object element):在指定位置添加元素
- Object get(int index):获得指定位置的元素
- int indexof(Object o):获得指定元素的首次出现的位置
- int lastIndextOf(Object o):获得指定元素的最后一次出现的位置
- Object remove(int index):移除指定位置的元素
- Object set(int index,Object element):替换某个位置的元素
ArrayList
LinkedList
Vector
底层通过数组实现。线程安全的。
所有的Collection类可以通过方法Collections.synchronizedList()输出为安全的。
4.Set集合
HashSet
特点:
- 存储时顺序和取出顺序不同
- 不可重复
- 放到HashSet集合中的元素实际上是放到HashMap集合的key部分。
TreeSet
特点:
- 存储时顺序和取出顺序不同
- 不可重复
- 读取顺序从小到大。
5.Map集合
Map和Collection之间没有继承关系。Map集合是以key和value(即键值对)的方式存储数据的。
特点:
- key和value是引用类型
- key和value都是存储对象的内存地址。
- key起到主导作用,value是它附属的值。
常用方法:
- V put(K key,V value):想Map集合中添加键值对
- V get(Object key):通过key获取value
- void clear():清空Map集合
- boolean containsKey(Object key):判断Map中是否包含某个key
- boolean containsValue(Object value):判断Map中是否包含某个value
- boolean isEmpty():判断Map中的元素个数是否为0
- Set
keySet():获取所有的key - V remove(Object key):删除Map集合中的某个键值对
- int size():获取map集合中的键值对的个数
- Collection
values():获取Map集合中所有的value,返回一个Collection - Set<Map.Entry<K,V>> entrySet():将所有的map集合转变为set集合。
遍历方法:
- keySet()方法获取map中所有的key生成set,通过遍历set,获得所有的value。
- entrySet()方法获取map中的Map.Entry生成set,通过遍历set,获取所有的value。
HashMap
特点:
1.HashMap集合底层是哈希表/散列表的数据结构
2.哈希表是一个数组和单向链表的结合体。
数组:在查询方面效率很高,增删效率很低。
单向链表:在增删方面效率较高,在查询方面效率很低。
哈希表将以上两种数据结构融合在一起,充分发挥各自的优点。
3.源代码:
“
public class HashMap<K,V> {
private static final long serialVersionUID = 362498820763181265L;
//HashMap底层实际上就是一个数组(一维数组)。
transient Node<K,V>[] table;
//静态的内部类HashMap.Node
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;//哈希表(哈希表是key的hashCode()方法的执行结果,hash值通过哈希函数/算法,可获得哈希码)
final K key;//存储到Map集合中的key
V value;//存储到Map集合中的value
Node<K,V> next;//下一个节点的内存地址
}
哈希表/散列表:一维数组,这个数组中每个元素是一个单向链表。
4.为什么哈希表查询和增删效率都高?
增删是在链表上进行的,查询只需要查询某一部分
5.为什么要重写hashCode方法和equals方法?
hashCode方法返回每个node的hash值,确定元素的数组下标位置。equals方法是判断key内容是否相同,不是内存地址。
6.我们需要保证哈希结构分布均匀,才能够发挥更好的性能,所以在重写hashCode方法时有一定的技巧。
7.HashMap集合的默认初始化容量是16,默认加载因子为0.75,就是HashMap底层数组的容量达到75%的时候,数组开始扩容。
HashMap集合初始化容量必须是2的倍数,这是官方推荐,这是因为达到散列均匀,为了能够提高HashMap集合的存取效率。
8.重写hashCode方法和equals方法
(1)向Map集合中存储,和Map集合中取,都是先调用key的hashCode方法,然后再调用equals 方法。
put(k,v),什么时候equals不会调用?
k.hashCode()方法返回哈希值。
哈希值经过哈希算法转换为数组下标
数组下标位置上如果是null,equals不需要执行。
拿get(k)举例,什么时候equals方法不会调用?
k.hashCode()方法返回哈希值
哈希值经过哈希算法转换为数组下标
数组下标位置上如果是null,equals不需要执行。
(2)注意:如果一个类的equals方法重写,那么hashCode方法必须重写。并且equals方法返回如果是true,hashCode()方法返回的值必须一样。equals方法返回true表示两个对象相同,在同一个单向链表上比较,那么对于同一个单向链表的结点来说,他们的哈希值都是相同的,所以hashCode()方法的返回值也应该相同。
9.Jdk8之后,哈希表单向链表中元素超过8之后,单向链表会变成红黑树。当红黑树上的结点小于6时,会重新将红黑树转为单向链表
结论:放在HashMap集合key部分的,以及放在HashSet集合中的元素,需要同时重写hashCode()方法和equals方法。
Hashtable
hashtable和hashmap基本上差不多,底层结构都是哈希表。
hashtable和hashmap之间的区别:
- hashtable集合中key和value都不能为null;hashmap集合中key和value都可以为null;
- hashtable集合中方法是synchronized的,线程安全的;而hashmap集合中方法是非synchronized的,线程不安全。
- hashtable因为线程安全,所以效率低;hashmap效率较高。
- hashtable初始容量为11,默认加载因子为0.75,扩容:newsize=oldsize2+1;hashmap初始容量为16,默认加载因子为0.75,扩容:newsize = oldsize2+1
Properties
Properties集合是一个Map集合,继承hashtable,Properties中的key和value都是String类型。
Properties被称为属性类对象。
常用方法:
- setProperty(String key,String value):设置集合中的键值对
- getProperty(String key):提取集合中的value
TreeMap
特点:
- TreeMap中的底层是一个二叉树。
- TreeMap集合中的元素是无序不重复的。但是会按照key的大小顺序自动排序,成为可排序集合。
对于自定义的类型,来说TreeMap是不能够进行自动排序的。如果我们需要排序,有两种方法:
方法一:
我们可以使自定义的类实现java.lang.Comparable接口。需要重写compareTo()方法,比较规则可以按照自己定的规则。
compareTo()返回值为int类型,结果大于0,在右子树找。结果小于0,在左子树找。
方法二:
创建自定义对象的比较器xxxComparator,实现java.util.Comparator,要使用泛型结构Comparator
两种方法的选择:
如果不需要经常改变比较规则,就选择实现Comparable接口。
如果需要经常改变比较规则,就选择创建comparator。
6.集合工具类Collections
常用方法:
- synchronizedList(List
list):将list集合变为安全的 - sort(List
list):将list变成可排序的,但是需要元素类型继承Comparable接口。
List、Set和Map集合之间的转换方法
List转Set:new Set
List转数组:list.toArray();
Set转List:new List
Set转数组:set.toArray(arr);
Map转List:key:new List
Map转Set:key:map.keySet();value:new Set
数组转List:Arrays.asList(arr);
数组转Set:new Set
读取集合中的方法
- 迭代器方法
- 普通遍历
- foreach方法
原创文章,作者:jamestackk,如若转载,请注明出处:https://blog.ytso.com/277410.html