java集合
什么是集合,为什么需要集合
集合是用来储存数据的容器。
在开发的过程中常常需要容器来存放数据,然后对数据进行处理。如数组。但是数组在初始化的时候就已经确定了容量,并且数组容量不可变,这样就会造成浪费或者空间不足的情况。集合就是用来解决此类问题的容器。
集合与数组的区别:
1、数组只能储存同一种类型的数据,而集合则能储存任意类型的对象(基础数据类型会装箱为包装类型的存储)。
2、数组一旦初始化其长度就固定,而集合的容量是可以随着数据的增长变大的。
集合的分类
一、集合的继承体系(图片来自网络)
上图实线表示实现类,虚线表示抽象类,点线表示接口。
二、主要集合类介绍
1、Collecttion 是所有单列集合的根接口,实现了Collection接口的类就可以称为集合类。
-------------| List 实现了该接口的集合类可以储存重复元素,并且元素是有序的。
-------------------------| ArrayList 内部维护着一个数组,特点是查询快,增删慢。
-------------------------| LinkedList 基于双向链表实现,特点是查询慢,增删块。
-------------------------| Vector内部也是维护了一个Object数组实现的, Arraylist是线程不安全 的,操作效率高,Vectoy是线程安全的,操作效率低。
-------------| Set 实现了该接口的集合类不能存储重复元素,并且元素是无序的。
-------------------------| HashSet 线程不安全,存取速度快,底层是以哈希表实现的。会根据hashcode()和equals判断元素是否重复(先判断hashcode再判断equals)。
-------------------------| TreeSet 红-黑树的数据结构,默认对元素进行自然排序(String)
-------------------------| LinkedHashSet 会保存插入顺序。
-------------| Queue保持一个队列(先进先出)的顺序。
2、Map是双列集合和Collection在集合体系中属于并列的存在。Map中存储的键值对,键唯一,值可以不唯一。
------------------------ | HashMap 底层采用的hash表实现,属于无序集合。非线程安全,可以存入null键和null值。
--------------------------------| LinkedHashMap:该子类基于哈希表又融入了链表。可以Map集合进行增删提高效率。
------------------------ | TreeMap 底层是二叉树结构,可以对键进行排序。
三、集合的遍历
1、普通的for循环遍历
2、增强for循环遍历(必须要是数组或者实现iterator接口)
3、迭代器遍历
所有的集合都有一个公共的父接口Iterator,实现了这个接口的集合类就能用增强for循环来对数据进行遍历。同时也能通过迭代器来对集合进行遍历。list还有一个反向迭代器。
代码如下:
public class TestClass {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("aa");
list.add("bb");
list.add("cc");
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
String next = iterator.next();
System.out.println(next);
}
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()){
String next = listIterator.next();
System.out.println(next);
}
while(listIterator.hasPrevious()){
System.out.println(listIterator.previous());
}
Map<String,Object> map = new HashMap<String,Object>();
map.put("1", "aaa");
map.put("2", "bbb");
map.put("3", "ccc");
Set<Entry<String,Object>> entrySet = map.entrySet();
Iterator<Entry<String, Object>> iterator2 = entrySet.iterator();
while(iterator2.hasNext()){
Entry<String, Object> next = iterator2.next();
System.out.println(next.getKey()+"-"+next.getValue());
}
}
}
四、集合中元素的排序。
1、List是有序集合,元素加入集合的顺序和元素保存的顺序是一致的。先加入的元素排在前面。
2、HashSet中是通过hashCode()方法得到的hashCode值来确定储存的位置,所以无法保证集合的有序性。LinkedHashSet同样也是通过hashCode来确定元素存储的位置,同时也会用链表来存储元素的加入顺序,遍历LinkedHashSet的时候会按照元素加入的顺序来进行遍历,这样看起来就像是有序集合一样。
3、TreeSet也是无序集合,但是可以按照一定的规则对元素进行排序。并且一个元素要想加入到TreeSet集合中来,必须得满足下面两个条件之一:①元素本身实现了接口Comparable中的CompareTo()方法;②自己定义一个比较器(实现Comparator接口中的compare()方法)并作为TreeSet的构造函数的参数传入,这样集合本身就会具备比较性。如果以上两个条件都不具备,这样将对象加入集合中就会报错。
4、HashTable和HashMap由于底层是hash表数据结构,所以也是无序集合。
5、LinkedHashMap同样也是hash表数据结构存储数据,但是还有一个链表结构来存储元素插入的顺序,在遍历该集合的时候可以按照元素插入的顺序来遍历,所以也算是有序集合。
6、TreeMap和TreeSet是一样需要Comparable接口或者Comparetor接口来实现键唯一和排序,并且通过查看TreeSet源码可以看出,其就是基于TreeMap构造出来的。