数组的缺点:
1. 数组空间长度一旦固定不可改变
2. 数组在添加、删除时很麻烦,效率低下 ==但是数组的随机访问/循环遍历效率是最高的==
3. 数组供我们直接使用的方法很少,几乎所有操作都是面向过程的
4. 数组没有提供对应的方法和属性来获取元素个数。只能通过循环来完成
5. 数组的存储是有序可重复的
单个元素存储:
Collection
接口: 无序,可重复的元素
List
接口:有序,可重复的元素
Set
接口:无序,不可重复的元素
实现类:
ArrayList
LinkedList
HashSet
TreeSet
键值对元素存储:
Map
接口: 以key-value
键值对形式存储
- 添加元素到末尾
add(E e)
- 将指定集合中的所有元素插入此列表中
addAll()
- 删除所有元素
clear()
- 列表中包含此元素返回
true
contains(Object o)
- 获取指定位置的元素
get(int index)
- 判空
isEmpty()
- 删除指定位置元素
remove(int index)
- 返回列表中元素个数
size()
add(E e)
在队尾添加元素addFirst(E e)
在队头插入元素addLast(E e)
在队尾添加元素 等效于add(E e)
removeFirst()
移除队头元素removeLast()
移除队尾元素pop()
继承自栈(出栈/弹栈),移除第一个元素 等效于removeFirst()
offer(E e)
队列常用方法,在队尾追加元素offerFirst(E e)
队列常用方法,在队头追加元素 等效于addFirst(E e)
offerLast(E e)
队列常用方法,在队尾追加元素 等效于addLast(E e)
Set
接口:存储 无序 唯一元素
Set
家族没有特有方法。主要弄懂实现唯一性的原理
无序,唯一、允许存储一个null元素
放入HashSet
中的对象需要重写 hashCode
和equals
方法
HashSet
集合去重原理:
1. 获得两个对象的哈希码,比较两个哈希码是否相同。如果不同就是两个不同的对象。如果hash
码相同:
2. 使用equals
比较内容。。若结果为false
表示两个对象不相同’。否则两个对象相同。HashSet
就不会存储这个数据了
所以用HashSet
存储的元素要求元素必须重写hashCode
和equals
方法。只有重写方法后才能去重。
有序、唯一、不允许null元素
确保元素唯一的原理:
借助比较器 (Comparable) 来模拟数据存入二叉树的三种结果:(-1, 0, 1)
想要让TreeSet
帮我们的自定义类对象去重,我们必须在自定义类中实现Comparable
接口并重写方法。
在自定义类中实现Comparable
接口 重写其中的compareTo
方法。自定义比较规则。这种方式叫做内部比较器。
但是这种做法的缺陷是,一个类只能重写一个比较方法,限制了类的使用场景。
解决这种缺陷的方法就是使用外部比较器。即在类外写一个比较器类 实现Comparator
接口。
在自定义比较器类中实现Comparator
接口,并重写其中的compare
方法。
以键值对key-value形式存储。
key: 无序、唯一
value: 无序、不唯一
允许空键和空值
在不使用Map的情况下,如果需要查询集合中一共存储了多少元素,调用size()方法即可。但是如果数据量非常大,这种查询方式就会消耗很多系统资源。因此java开发者们想出了使用Map这种键值对形式来存储大量数据。
Map
接口的实现类用法同List
和 Set
不同。以下介绍几个常用方法:
put(K,V)
插入数据remove(K)
移除数据replace(K,V)
替换指定key
对应的值size()
返回图中的键值对数量KeySet()
返回该图中键的集合isEmpty()
判空get(K)
获取指定键映射的值values()
返回所有值的Collection
集合entrySet()
返回键值对的Set
集合
//1.第一种 : 迭代器
Set<Integer> set = map.keySet();
Iterator<Integer> iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(map.get(iterator.next()));
}
//2.第二种方式 :foreach
Set<Integer> set1 = map.keySet();
for (Integer i:set1) {
System.out.println(map.get(i));
}
//3.第三种方式 直接拿
Collection<SetTest.Student> values = map.values(); //获取map集合中value的集合
for (SetTest.Student student: values) {
System.out.println(student);
}
//4.第四种 entrySet
//如何确保K唯一? 重写比较器
Set<Map.Entry<Integer, SetTest.Student>> sett = map.entrySet(); //获取KV对象集合
for (Map.Entry<Integer, SetTest.Student> entry: sett) {
System.out.println(map.get( entry.getKey()));
}
-
迭代方式: 你可以使用增强型 for 循环或迭代器来遍历
List
和Set
集合中的元素。 -
添加和删除元素: 你可以使用
add
方法来添加元素,使用remove
方法来删除元素。 -
查找元素: 你可以使用
contains
方法来检查集合中是否包含某个元素。 -
大小: 你可以使用
size
方法获取集合的大小。 -
接口方法: 一些通用的方法,如
isEmpty
、clear
等,在这两个接口的实现类中都有类似的用法。
不同之处:
-
顺序性:
List
接口的实现类(如ArrayList
、LinkedList
)保留了元素的插入顺序,而Set
接口的实现类(如HashSet
、TreeSet
)则不保留元素的插入顺序。 -
元素唯一性:
Set
接口的实现类要求元素唯一,而List
接口的实现类允许重复元素。 -
索引访问:
List
接口的实现类允许你通过索引来访问元素,例如list.get(index)
,而Set
接口的实现类没有这样的方法。 -
有序性:
List
接口的一些实现类允许你根据元素的位置来操作集合,如ArrayList
和LinkedList
提供了在指定位置插入和删除元素的方法,而Set
接口的实现类不提供这些方法。
ArrayList
:随机访问高效,动态增长,但插入和删除元素可能较慢。LinkedList
:插入和删除高效,支持双向链表操作,但随机访问较慢。HashSet
:无序集合,快速查找和去重,基于哈希表。TreeSet
:有序集合,基于红黑树,支持有序遍历和范围查找。HashMap
:键值映射,快速查找和插入键值对,基于哈希表。TreeMap
:有序键值映射,支持按键的自然顺序或自定义顺序遍历。