Skip to content

Latest commit

 

History

History
152 lines (121 loc) · 6.75 KB

9-集合.md

File metadata and controls

152 lines (121 loc) · 6.75 KB

集合的引入

数组的缺点

1. 数组空间长度一旦固定不可改变
2. 数组在添加、删除时很麻烦,效率低下  ==但是数组的随机访问/循环遍历效率是最高的==
3. 数组供我们直接使用的方法很少,几乎所有操作都是面向过程的
4. 数组没有提供对应的方法和属性来获取元素个数。只能通过循环来完成
5. 数组的存储是有序可重复的

集合的结构图

单个元素存储:

Collection接口: 无序,可重复的元素

List接口:有序,可重复的元素

Set接口:无序,不可重复的元素

实现类:

ArrayList

LinkedList

HashSet

TreeSet

键值对元素存储:

Map接口: 以key-value键值对形式存储

List接口

ArrayList实现类

  1. 添加元素到末尾 add(E e)
  2. 将指定集合中的所有元素插入此列表中 addAll()
  3. 删除所有元素 clear()
  4. 列表中包含此元素返回true contains(Object o)
  5. 获取指定位置的元素 get(int index)
  6. 判空 isEmpty()
  7. 删除指定位置元素 remove(int index)
  8. 返回列表中元素个数 size()

LinkedList实现类

  1. add(E e) 在队尾添加元素
  2. addFirst(E e) 在队头插入元素
  3. addLast(E e) 在队尾添加元素 等效于 add(E e)
  4. removeFirst() 移除队头元素
  5. removeLast() 移除队尾元素
  6. pop() 继承自栈(出栈/弹栈),移除第一个元素 等效于removeFirst()
  7. offer(E e) 队列常用方法,在队尾追加元素
  8. offerFirst(E e) 队列常用方法,在队头追加元素 等效于addFirst(E e)
  9. offerLast(E e) 队列常用方法,在队尾追加元素 等效于addLast(E e)

Set接口

Set接口:存储 无序 唯一元素

Set家族没有特有方法。主要弄懂实现唯一性的原理

HashSet实现类

无序,唯一、允许存储一个null元素

放入HashSet中的对象需要重写 hashCodeequals方法

HashSet集合去重原理:
1. 获得两个对象的哈希码,比较两个哈希码是否相同。如果不同就是两个不同的对象。如果hash码相同:
2. 使用equals比较内容。。若结果为false表示两个对象不相同’。否则两个对象相同。HashSet就不会存储这个数据了
所以用HashSet存储的元素要求元素必须重写hashCodeequals方法。只有重写方法后才能去重。

TreeSet实现类

有序、唯一、不允许null元素

确保元素唯一的原理:

借助比较器 (Comparable) 来模拟数据存入二叉树的三种结果:(-1, 0, 1) 想要让TreeSet帮我们的自定义类对象去重,我们必须在自定义类中实现Comparable接口并重写方法。

内部比较器Comparable

在自定义类中实现Comparable接口 重写其中的compareTo方法。自定义比较规则。这种方式叫做内部比较器。 但是这种做法的缺陷是,一个类只能重写一个比较方法,限制了类的使用场景。 解决这种缺陷的方法就是使用外部比较器。即在类外写一个比较器类 实现Comparator接口。

外部比较器Comparator

在自定义比较器类中实现Comparator接口,并重写其中的compare方法。

Map接口

以键值对key-value形式存储。
key: 无序、唯一
value: 无序、不唯一
允许空键和空值
在不使用Map的情况下,如果需要查询集合中一共存储了多少元素,调用size()方法即可。但是如果数据量非常大,这种查询方式就会消耗很多系统资源。因此java开发者们想出了使用Map这种键值对形式来存储大量数据。

HashMap实现类

Map接口的实现类用法同ListSet 不同。以下介绍几个常用方法:

  1. put(K,V) 插入数据
  2. remove(K) 移除数据
  3. replace(K,V) 替换指定key对应的值
  4. size() 返回图中的键值对数量
  5. KeySet() 返回该图中键的集合
  6. isEmpty() 判空
  7. get(K) 获取指定键映射的值
  8. values() 返回所有值的Collection集合
  9. entrySet() 返回键值对的Set集合

HashMap的四种遍历

//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()));  
}

总结

List和Set接口

  1. 迭代方式: 你可以使用增强型 for 循环或迭代器来遍历 ListSet 集合中的元素。

  2. 添加和删除元素: 你可以使用 add 方法来添加元素,使用 remove 方法来删除元素。

  3. 查找元素: 你可以使用 contains 方法来检查集合中是否包含某个元素。

  4. 大小: 你可以使用 size 方法获取集合的大小。

  5. 接口方法: 一些通用的方法,如 isEmptyclear 等,在这两个接口的实现类中都有类似的用法。

不同之处:

  1. 顺序性: List 接口的实现类(如 ArrayListLinkedList)保留了元素的插入顺序,而 Set 接口的实现类(如 HashSetTreeSet)则不保留元素的插入顺序。

  2. 元素唯一性: Set 接口的实现类要求元素唯一,而 List 接口的实现类允许重复元素。

  3. 索引访问: List 接口的实现类允许你通过索引来访问元素,例如 list.get(index),而 Set 接口的实现类没有这样的方法。

  4. 有序性: List 接口的一些实现类允许你根据元素的位置来操作集合,如 ArrayListLinkedList 提供了在指定位置插入和删除元素的方法,而 Set 接口的实现类不提供这些方法。

总结特点

  • ArrayList:随机访问高效,动态增长,但插入和删除元素可能较慢。
  • LinkedList:插入和删除高效,支持双向链表操作,但随机访问较慢。
  • HashSet:无序集合,快速查找和去重,基于哈希表。
  • TreeSet:有序集合,基于红黑树,支持有序遍历和范围查找。
  • HashMap:键值映射,快速查找和插入键值对,基于哈希表。
  • TreeMap:有序键值映射,支持按键的自然顺序或自定义顺序遍历。