集合:用来存放对象的容器。
注:集合只能存放对象( 存放基本类型会自动转换为引用类型 )。
集合存放的是多个对象的引用,对象本身还是存放在堆内存中。
集合可以存放不限数量、不限类型的对象。
集合详解:
1、Iterator迭代器:它是Java集合的顶层。(Map的顶层接口是Map接口)
Collection接口继承的是Iterable接口。
Iterable和Iterator接口的区别:Iterable接口封装了Iterator接口,只要实现了Iterable接口就可以使用Iterator迭代器。
为什么实现Iterable接口而不直接实现Iterator接口?
因为Iterator接口的核心方法next()和hasNext()都是依赖于迭代器的当前迭代位置的。如果Collection直接继承Iterator接口就会导致集合对象中包含当前迭代位置的数据。当集合在不同方法间传递时,由于当前位置的不可预知就会导致next()方法返回的结果不可预知。而Iterable则不然,每次开始调用都会返回一个从头开始计数的迭代器。多个迭代器不会相互干扰。
2、Collection:List和Set的父接口。
3、List:有序、可重复的集合。
List集合的三个典型实现:
List<> arrayList = new ArrayList<>(); //ArrayList底层结构是数组,查询快,增删慢;线程不安全,效率高。
List<> vector = new Vector<>(); //Vector底层结构是数组,查询快,增删慢;线程不安全,效率低。
List<> linkedList = new LinkedList<>(); //LinkedList底层数据结构是双向链表,查询慢,增删快,线程不安全,效率高。
常用方法:
.add():向集合中添加元素。
.addAll():向末尾添加另一个Collection
.clear():清除所有元素
.contains():集合中是否包含指定元素
.containsAll():集合中是否包含另一个Collection的所有元素
.get():返回集合指定位置的元素
.indexOf():返回集合中第一次出现集合的位置,若没有则返回-1
.remove():删除元素
ArrayList.removeFirst():返回并删除第一个元素
4、Set:无序不可重复的结合
Set<> hashSet = new HashSet<>();
1) 不能保证元素的顺序,不可重复,线程不安全,元素可以为null。
2) 底层是数组,存在的目的是加快查询速度。HashSet的底层数组的索引和值有一个确定的关系:index = hash(value)。只需调用这个公式就能快速的找到元素或索引。
3) 对于HashSet,如果两个对象通过equals返回true,则必须保证这两个对象的hashCode相同。
Set<> linkedHashSet = new LinkedHashSet<>();
是HashSet的子类。有序不可重复,底层采用链表和哈希表的算法。链表保证元素的添加顺序,哈希表保证元素唯一性。
Set<> treeSet = new TreeSet<>();
有序不可重复,底层采用红黑树算法。擅长范围查询。
注:TreeSet的集合元素不能为null;必须放入同类的元素;自动排序。
常用方法:
.add():增加元素
.remove():删除元素
.removeAll(Set):删除包含的Set
5、Map:key-value键值对,key不允许重复,value允许重复。
1) 严格来说Map并不是一个集合,它是两个集合之间的映射。
2) 这两个每一条数据通过映射关系可以可以看成是一条数据,即Entry(key,value)。Map可以看成是多个Entry组成的。
3) 因为Map既没实现Collection接口又没实现Iterator接口,所有无法用foreach对Map遍历。
典型实现
//线程不安全
HashMap<T> hashMap = new HashMap<T>();
//线程安全
Hashtable<T> hashTable = new Hashtable<T>(); //利用synchronized关键字,get和set不能被同时访问。
Map<T> concurrentHashMap = new ConcurrentHashMap<T>(); //CAS算法保证线程同步
Map<T> synchronizedMap = Collections.synchronized(new HashMap<T>());
//有序
TreeMap<T> treeMap = new TreeMap<T>(); //根据key排序,默认升序。
LinkedHashMap<T> linkedHashMap = new LinkedHashMap<T>(); //根据数据插入顺序排序。
遍历集合
Map<String,Object> hashMap = new HashMap<String,Object>();
//通过Map.keySet()得到Map的key集合,再通过get()得到value。
Set<String> set = hashMap.keySet();
for(String str : set){
Object obj = hashMap.get(str);
}
//通过Map.entrySet()得到Map的Entry集合,然后遍历。
//Map.entrySet是键值对的集合,集合里面的类型是Map.Entry(Map的一个内部接口)
Set<Map.Entry<String,Object>> entrys = hashMap.entrySet();
for(Map.Entry<String,Object> entry : entrys){
String key = entry.getKey();
Object value = entry.getValue();
}
常用方法:
.put(key,value):添加一组Map,若key已存在则覆盖原key
.remove(key):删除一条数据
putAll(Map t):将来自特定映像的所有元素添加给该映像
.clear():删除所有映射
containsKey(Object key): 判断映像中是否存在关键字key
containsValue(Object value): 判断映像中是否存在值value
.keySet():返回key的集合
.entrySet():返回类型为Entry<?,?>的集合
6、Map和Set的关系
1) 都有几个类型的集合
HashMap和HashSet、TreeMap和TreeSet、LinkedHashMap和LinkedHashSet。
2) Set集合就是Map集合的key组成。
除Map外所有的集合类都实现了Iterator接口( 迭代器 ),这是一个用来遍历集合元素的接口,主要有hasNext()、next()、remove()三个方法。它的一个子接口ListIterator又增加了add()、previous()、hasPrevious()三个方法。
无序的集合实现Iterator接口,只能从前往后遍历,如HashSet。有序的集合实现ListIterator接口,既可以从前往后遍历又可以通过previous从后往前遍历,如ArrayList。