集合
本文介绍Java中的基本集合,包括集合的概念以及集合接口Collectiion中实现类,List,Set,queue和map、常用集合工具类。
**
Collection集合
**
集合(Collection)接口位于Set接口和List接口的最顶层,是Set接口和List接口的父接口。Collection接口中定义了Collection对象共有的一些基本方法,这些方法分为基本操作、批量操作和数组操作。
**
List接口
-
List中的元素是有顺序的。
-
List通常允许重复元素。
-
List的实现类通常支持null元素。
-
可以通过索引访问List对象容器中的元素。
1)ArrayList
List接口的实现类包括AbstractList、AbstractSequentialList、ArrayList、AttributeList、CopyOnWriteArrayList、LinkedList、RoleList、RoleUnresolvedList、Stack、Vector。实际项目开发中,最常用的是ArrayList、LinkedList。
1)ArrayList
ArrayList在概念上与数组类似,表示一组编入索引的元素,区别之处在于ArrayList没有预先确定的大小,其长度可按需增大
ArrayList底层是基于数据结构的集合,使用数组的复制,来完成集合的扩容或缩容。List list = new ArrayList<>();//新创建一个list集合 list.add(123);//add往集合里添加数据 list.add(123); list.add("asdf"); list.add("asdf"); list.set(1, "张三");// 修改元素set第1个参数是待修改元素的下标,第二个参数是修改的值 Iterator it = list.iterator();//可以通过迭代器遍历集合 while (it.hasNext()) {//it.hasNext()集合中有元素 Object obj = it.next();//获取元素 System.out.println(obj); it.remove();// 如果需要从集合中,移除元素才使用该方法 } System.out.println(list.size());//通过size方法获得集合中元素的的个数 int size = list.size();// 元素个数 for (int i = 0; i < size; i++) { System.out.println(list.get(i));//获得集合中的元素 }
2) LinkedList
LinkedList是实现了双向链表功能的列表,它将列表中的每个对象放在独立的空间中,而且每个空间中还保存有上一个和下一个链接的索引
List ll = new LinkedList<>();//新建一个LinkList类型的集合
ll.add(123);//添加
ll.add(123);
ll.add("asdf");
ll.add("asdf");
ll.add(null);
ll.remove(p1);//移除
System.out.println(ll.size());
3)vector
同步的集合,在多线程时,仅单进程访问。
ArrayList,LinkedList,Vector
三者均是List实现类,都可以代表有序,重复集合。
但是:ArrayList底层时基于数组结构来实现,查询数据较快,操作数据慢
LinkedList 底层是基于链表结构来实现,查询数据慢,但操作数据较快
Vector同ArrayList一致,唯一区别是同步方法,效率比不上Arraylist.
List list3 = new Vector<>()
**
Set接口
**
Set集合中不能包含重复元素。
Set实现
HashSet<>():速度快,无序的。
TreeSet:有序的,有序的。
TreeSet的底层是TreeMap,TreeMap采用二叉树的结构存储。
在二叉树中,比较元素时,比树中元素小的,永远在下一代的左边
当然,比树中元素大的,永远在下一代的右边,相等的,直接覆盖。
只能存放相同类型的数据。
Set set = new HashSet<>();
set.add("abc");
set.add(123);
set.add(new Dog());
System.out.println(set.isEmpty());
System.out.println(set.size());
for (Object obj : set) {
Person person = (Person) obj;
System.out.println(person);
}
**
HashMap()键值对结构
**
泛型用来泛指数据类型,指Object
HashMap中,如果是我们自己定义的类的对象,必须重写hashcode()和equals(),上层的hashSet也同理。
HashMap底层是数组+单向链表的结构,数组用于存放键的hash值,而链表用于存储k-v结构
数组构成了HashMap中的Hash表,表的大小默认是16,可以存放的数据是16加载因子0.75
当超过160.75个数据时,Hash表将自动扩容,扩容的后的大小是16*2^n
Map map = new HashMap();//新建hashMap
map.put("001", "张三");//通过键值对,把数据放入其中。其中键唯一
map.put("002", "李四");
map.put("003", "王五");
map.get("003");//通过键获得值
Set keys=map.keySet();//获取所有的键
map.remove("001");//通过键移除该键值对
Iterator iterator = keys.iterator();//迭代器
while(iterator.hasNext()) {
Object key = iterator.next();//得到键了
System.out.println(map.get(key));
}
HashMap示意图如下:
HashTable和HashMap的区别
1、 HashTable是线程安全的,HashMap是线程非安全
2、 HashMap中允许存放空键(只允许一次),HashTable中不允许出现空键空值。
Collections和Collection的区别
Collection是list列表集合,和Set集合的父接口
Collections是集合工具类
Properties只能存放字符串
**
hash算法流程如下: