什么是集合
集合类存放于java.util包中,主要有list(列表), set(集), map(映射),集合存放的都是对象的引用而非对象本身,所以我们称集合中的对象就是集合中对象的引用。简而言之,集合就是存放数据对象引用的容器。
List
1.List概述
List集合是有序的,可以对其中每个元素的插入位置进行精确地控制,通过索引来访问元素,遍历元素。常用地主要有ArrayList和LinkedList这两个类。
其中ArrayList底层是通过数组实现,随着元素的增加而动态扩容;而LinkedList底层是通过链表实现,随着元素的增加不断向链表的后端增加节点。
2.List方法
3.List特点
- 可以允许重复的对象。
- 可以插入多个null元素。
- 是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。
- 常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。
ArrayList
1.ArrayList概述
ArrayList是一个数组队列,线程不安全集合,它允许对元素进行快速随机访问,数组的缺点是每个元素之间不能有间隔,当数组大小部门组时需要增加存储能力,就需要将已经有数组的数据复制到新的存储空间中(copyOf),当从ArrayList的中间位置插入或者删除元素时,需要对数组进行赋值、移动,代价比较高,因此,它适合随机查找和遍历,不适合插入和删除。
ArrayList继承自AbstractList,实现了如下接口:
- 实现了List,得到了List集合框架的基本功能;
- 实现了RandomAccess(这是一个标记接口,没有任何方法),获得了快速随机访问存储元素的功能,???如何获得的这个功能
- ArrayList实现了Cloneable,得到clone()方法,可以实现克隆功能;
- 实现了Serializable,表示可以被序列化,通过序列化去传输。
2.ArrayList方法
3.ArrayList特点
- 容量不固定,随着容量的增加而动态扩容
- 有序集合
- 插入的元素可以是null
- 增删改查效率比LinkedList高
- 线程不安全,只能用在单线程环境下
LinkedList
1.LinkedList概述
LinkedList底层采用的是双向链表结构,很适合数据的动态插入和删除,但是LinkedList存储元素的节点需要额外的空间存储前驱和后继的引用,并且随机访问和遍历速度比较慢。另一方面,LinkedList在链表头部和尾部插入效率较高,但在指定位置进行插入时,效率一般(因为在指定位置插入需要定位到该位置处的节点O(n)),最后,LinkedList是非线程安全的集合类。
2.LinkedList方法
代码示例
public static void main(String[] args) {
//将一个数组变成List集合
int[] data = {1,3,5,7,9,11,11,13};
List<Integer> list = new ArrayList<>();
for (int i = 0; i < data.length; i++) {
//增加
list.add(data[i]);
}
//删除
list.remove(1);
//将下标 0位置元素改为 666
list.set(0,666);
System.out.println(list);
//查找
System.out.println(list.contains(2));
System.out.println(list.get(2));
}
//输出结果:
[666, 5, 7, 9, 11, 11, 13]
false
7
Set
Set概述
Set继承自Collection接口,是一个不允许出现重复元素并且无序的集合,主要有HashSet和TreeSet两大实现类。在判断重复元素的时候,Set集合会调用hashCode()和equal()方法来实现。HashSet是哈希表结构,主要利用HashMap的key来存储元素,计算插入元素的hashCode()来获取元素在集合中的位置;TreeSet是红黑树结构,每一个元素都是树中的一个节点,插入的元素都会进行排序。
Set:
- 不允许重复对象
- 无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序。
- 只允许一个 null 元素
- Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。
HashSet
1.HashSet概述
hashSet实现Set接口,底层由HashMap实现,为哈希表结构,新增元素相当于HashMap的key,value默认为一个固定的Object。
(1)HashSet继承AbstractSet类,获得了Set接口大部分的实现,减少了实现此接口所需的工作,实际上是又继承了AbstractCollection类;
(2)HashSet实现了Set接口,获取Set接口的方法,可以自定义具体实现,也可以继承AbstractSet类中的实现;
(3)HashSet实现Cloneable,得到了clone()方法,可以实现克隆功能;
(4)HashSet实现Serializable,表示可以被序列化,通过序列化去传输,典型的应用就是hessian协议。
HashSet特点:
- 不允许出现重复因素;
- 允许插入Null值;
- 元素无序(添加顺序和遍历顺序不一致);
- 线程不安全,若2个线程同时操作HashSet,必须通过代码实现同步。
2.HashSet方法
代码示例
public static void main(String[] args) {
int[] data = {1,1,2,3,3,4,4,5,5,6,6,7};
Set<Integer> set = new HashSet<>();
for (int i = 0; i < data.length; i++) {
set.add(data[i]);
}
System.out.println(set);
System.out.println(set.contains(7));
}
//输出结果:[1, 2, 3, 4, 5, 6, 7]
true
Map
1.Map概述
Map与 Collection 并列存在。用于保存具有 映射关系 的数据 :key-value。
Map 中的 key 和 value 都可以是任何引用类型的数据。
Map 中的 key 用 Set 来存放, 不允许重复 ,即同一个 Map 对象所对应的类,须重写hashCode() 和 equals() 方法。
常用 String 类作为 Map 的“键”。
key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到唯一的、确定的 value。
Map 接口的常用实现类: HashMap 、 TreeMap 、 LinkedHashMap 和Properties。其中, HashMap 是 Map 接口使用频率最高的实现类。
HashMap
1.HashMap概述
HashMap 实现了Map接口
HashMap 根据键的 hashCode 值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。 HashMap 最多只允许一条记录的键为 null,允许多条记录的值为 null。HashMap 非线程安全,即任一时刻可以有多个线程同时写 HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 Collections 的 synchronizedMap 方法使HashMap 具有线程安全的能力,
2.HashMap方法
代码示例
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
//key值为学号,value为姓名
map.put(1,"张三");
map.put(2,"李四");
map.put(8,"王五");
System.out.println(map);
//当key重复时,更新值
map.put(1,"李铁蛋");
System.out.println(map);
System.out.println(map.get(2));
System.out.println(map.getOrDefault(19,"0"));
System.out.println(map.remove(8));
System.out.println(map);
}
// 输出:{1=张三, 2=李四, 8=王五}
{1=李铁蛋, 2=李四, 8=王五}
李四
0
王五
{1=李铁蛋, 2=李四}