List、Set、Map、Collections

1.List

概念
    单列集合 继承自Collection,还是一个接口,不是一个实现类
集合框架体系图

特点

  • 元素可重复
  • 有索引的
  • 元素有序(存元素的顺序和去元素的顺序是一样的)

常用方法

  • void add(int index,E element) —>向指定索引添加元素
  • E get(int index) —>根据索引去元素
  • E remove(int index) —>根据索引删元素
  • E set(int index,E element) —>用指定元素替代集合中指定位置的元素,返回被替换元素

实现类

ArrayList

概念

  • List实现类
  • 该集合的数据结构是一个数组

特点
    查询快,增删慢
方法
    没有特有的方法

问题:
    ArrayList底层是数组,而数组长度是不可变的,但是ArrayList集合可以改变长度。它的底层是数组复制 —>copyOf —>System.ArrayCopy,所以操作元素比较慢!
    需求:往集合中添加5个元素,之后
        1.直接在集合开头添加元素
        2. 在集合末尾添加元素
        3. 删除集合第一个元素
        4. 删除集合最后一个元素
当遇到上面这种需求,就有点瓜皮了。因此出现了下面的类

LinkedList

概念

  • List实现类
  • 查询慢,增删快
  • 该集合数据结构是一个链表结构(双向链表)

特点

  • 元素有序
  • 有大量的特有方法去操作首尾元素

方法

扫描二维码关注公众号,回复: 10577064 查看本文章
  • void addFirst(E e) —>将指定元素插入到列表开头。
  • void addLast(E e) —>将指定元素添加到列表结尾。
  • E getFirst() —>获取第一个
  • E getLast() —>获取最后一个
  • E removeFirst() —>删除第一个
  • E removeLast() —>删除最后一个
  • E pop() —>从此列表所表示的堆栈处弹出一个元素
  • void push(E e) —>将元素推入此列表所表示的堆栈
  • booleanisEmpty() —>如果列表不包含元素,则返回true。

总结
    从LinkedList中的Node对象来看,是一个双链表,一个节点记录着上一个节点的地址,也记录着下一个节点的地址。


2.Collections

概念
    专门操作集合的工具类

特点
    方法全静态使用时类名直接调用

方法

  • static void shuffle(List<?> list) —>打乱集合顺序
  • sort(List list) —>将集合元素按照默认规则排序(按编码表排序)
  • sort(List list, Comparator<? super T> c)
    Comparator是一个接口 —>比较器
    利用实现类使用,重写Comparator中的方法
    int compare(T o1, T o2) —>前面的参数减去后面的参数(升序),反过来(降序)
//使用匿名内部类重写Comparator中的方法int compare(T o1, T o2) 
public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return 01-02;//前面的参数减去后面的参数(升序)
            }
        });
    }

可变参
使用场景

  • 方法参数只确定参数类型,不确定方法参数
  • 本质是一个数组
    使用
    定义格式
public static void method(int...i){}

调用格式

method(1,2,3,4,5,6);//可以有很多

注意
    一个方法中只能定义一个可变参数
    可变参数可以和普通参数同时出现,但可变参数必须放在参数的最后边


3.Set

概念
    方法(没有特有方法)

使用
    根据实现类创建对象

特点

  • 不允许出现重复元素
  • 无序(LinkedHashSet是有序的)
  • 没有索引,只能用迭代器和增强for遍历

实现类

HashSet

特点

  • 不允许出现重复元素
  • 无序(存进去的顺序和第一次取出来的顺序不一致)
  • 没有索引,只能用迭代器和增强for遍历
  • 底层数据结构:哈希表结构

使用
    和Collection没有区别
    HashSet本身没有功能,依靠HashMap进行的

无参构造:默认初始容量为16,加载因子为0.75F
有参构造
    HashSet(int initialCapacity,float loadFactor)
        initialCapacity:初始容量
        loadFactor:指定的加载因子

但是通过分析源码得知:创建HashSet无需指定初始容量和加载因子,因为HashSet底层的算法计算后初始容量还是逃不了16的倍数。因此有参构造基本不用。

哈希表结构
哈希值概念:
    由计算机算出来的一个十进制数,可以理解为对象的地址值(逻辑地址),内存分配给对象的地址值和哈希值没啥关系。谁都不知道内存地址长什么样。
获取哈希值
    对象.hashCode();
字符串哈希值
    String重写了hashCode方法,计算的是字符串里的内容的哈希值,特别注意的是字符串内容不相等,哈希值也有可能相等。比如:abc acD
结论
    内容一样,哈希值一定一样
    内容不一样,哈希值也有可能一样

hashSet如何保证数据唯一
    先获取元素哈希值(存储的元素类型重写的hashCode)进行比较,如果哈希值相等 在比较内容,如果哈希值不相等,那么内容肯定不相等。
    1.哈希值不一样 直接存
    2.哈希值不一样,但是内容不一样,也可以存
    3.哈希值一样,内容也一样,证明完全是一个元素,HashSet直接去重复。
hashSet存储自定义类型如何保证元素唯一
    1.在自定义类中重写HashCode方法。
    2.重写后的方法比较的是类中成员的哈希值。

哈希表
jdk8之前
    哈希表 = 数组+链表
jdk8之后
    哈希表 = 数组+链表(单向链)+红黑树

注意
    哈希表中的数组长度默认是16
    哈希值模16余几就存入对应下标
    如果链表长度超过8个,就会自动变成红黑树存储。

哈希表储存过程
当元素快超过了数组长度怎么办??
    加载因子
        0.75F ->如果往哈希表存元素达到了数组的百分之75,自动扩容2倍。扩容后下次存元素就不是模16余了而是模32。以此类推…

LinkedHashSet

概念

  • 继承自HashSet
  • 数据结构:链表+哈希表

特点

  • 元素唯一
  • 没有索引
  • 有序

TreeSet

概念

  • Set实现类
  • 基于红黑树的实现

特点
    查询快

作用
    使用元素的自然排序规则,对集合中的元素进行排序(内部会使用Comparator比较器进行默认的升序)

构造方法

  • TreeSet() —>默认升序
  • TreeSet(Comparator<? super E> comparator) —>指定排序规则。

4.Map

概念

  • 双列集合顶级接口
  • 键必须唯一,不能重复.
  • 无序(但是实现类中有一个LinkedHashMap是有序的)
  • 没有索引
  • 储存元素的特点:键值对的形式

实现类

HashMap<K,V>

概念

  • 键必须唯一,不能重复.
  • 无序
  • 没有索引
  • 储存元素的特点:键值对的形式
  • 数据结构:哈希表

方法

  • V put(K key,V value):把指定的键与指定的值添加到Map集合
  • V remove(Object key):根据键删除对应的值,返回被删除的值
  • V get(Object key):根据键获取值
  • boolean containsKey(Object key):判断该集合中是否有此键
  • Set< K> keySet():获取Map集合所有的键,存到Set集合中. —>用于遍历HashMap集合
		//Set< K> keySet()
        Set<Integer> keySet = hashMap.keySet();
        for (Integer key : keySet) {
            System.out.println(key);
        }
  • Set<Map.Entry<K,V>> entrySet():获取到Map集合中所有的键值对对象.—>用于遍历HashMap集合
    Entry:是Map中的静态的内部接口,记录着Key和value的一个对象.
    Map.Entry获取Entry

     K getKey():获取key
     V getValue():获取value

        //Set<Map.Entry<K,V>> entrySet()
        Set<Map.Entry<Integer, String>> entries = hashMap.entrySet();
        for (Map.Entry<Integer, String> entry : entries) {
            int k = entry.getKey();
            String v = entry.getValue();

            System.out.println(k+"="+v);
        }

注意

  • 如果键重复,后添加的会把前添加的干掉
  • Key值可以为null

如何保证键唯一:
    键需要重写hashCode和equals判断过程和HashSet一摸一样

HashMap存储自定义类型:key为自定义类型
如何保证Key唯一?

    重写HashCode和equals

LinkedHashMap

概念
    是HashMap的子类

特点

  • 键唯一

  • 有序(数据结构 = 哈希表+链表)

  • 没有索引

  • 用法和HashMap一毛一样。

TreeMap

概念
    实现Map接口
    基于红黑树实现(查询贼快)

作用
    可以对key进行排序

构造方法
    TreeMap():针对key进行自然排序,默认升序
    TreeMap(Comparator<? super K> comparator) :可以指定排序规则.

发布了30 篇原创文章 · 获赞 39 · 访问量 2058

猜你喜欢

转载自blog.csdn.net/weixin_44564242/article/details/104914544