IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java 集合(底层解析) -> 正文阅读

[Java知识库]Java 集合(底层解析)

Java 集合(底层解析)

  • 使用数组存储对象具有一些弊端,而Java集合就像一种容器,可以动态的把多个对象的引用放入容器中
  • 数组在内存中存储的特点:
    • 数组初始化以后,长度就确定了
    • 数组声明的类型,就决定了进行元素初始化的类型
  • 数组在存储数据方面的弊端:
    • 数组初始化以后,长度就不可变了,不便于扩展
    • 数组中提供的属性和方法少,不便于进行添加,删除,插入等操作,且效率不高,同时无法直接获取存储元素的个数
    • 数组存储的数据是有序的,可以重复的。 存储数据的特点单一
  • Java集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组

1、Collection 接口

单列数据,定义了存取一组对象的方法的集合

iterator() :返回 Iterator 接口的实例,用于遍历集合元素

  • Iterator 对象称为迭代器(设计模式的一种),主要用于遍历Collection 集合中的元素
  • 迭代器模式的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的细节。迭代器模式,就是为容器而生。
  • Collection接口继承了Iterable接口,该接口有一个iterator() 方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用于返回一个实现了Iterator接口的对象
  • Iterator 仅用于遍历集合,Iterator 本身并不提供承装对象的能力。如果需要创建Iterator对象,则必须有一个被迭代的集合
  • 集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认指针都在集合的第一个元素之前。

1.1 List

元素有序、可重复的集合。

  • ArrayList:作为List的主要实现类,线程不安全的,效率高,底层使用数组存储

    // 底层分析
    // JDK 1.7
    ArrayList list = new ArrayList();// 底层创建了长度是10的Object[]数组
    list.add(123)...;// 如果此次的添加导致底层elementData数组容量不够,则扩容
    // 默认情况下,扩容为原来容量的1.5倍,同时将原有数组中的数据复制到新的数组中
    // 开发中建议使用带参的构造器:指定初始长度,避免不必要的扩容,增加效率
    
    // JDK 1.8
    ArrayList list = new ArrayList();// 底层Object[] elementData初始化为{},并没有创建长度为10的数组
    list.add(123);// 第一次调用add()时,底层才创建了长度为10的数组,并将数据添加到elementData数组中,后期扩容一样
    // 延迟了数组的创建,节省内存·
    
  • LinkedList:底层使用双向链表存储,对于频繁的插入、删除操作,比ArrayList效率高

    // 底层分析
    LinkedList list = new LinkedList();// 内部声明了Node类型的first和last属性,默认值为null
    list.add(123);// 将123封装到Node中,创建了Node对象。
    // 其中,Node定义为:
    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;
        
        Node(Node<E> prev,E element,Node<E> next){
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
    
  • Vector:线程安全的,效率低,底层使用数组存储

    // Vector底层源码分析:通过构造器创建对象时,底层都是创建了长度为10的数组
    // 在扩容方面,默认扩容为原来数组的2倍。
    

1.2 Set

元素无序、不可重复的集合。

以HahSet为例:

  1. 无序性:不等于随机性。存储的数据在底层数组(初始长度16,当使用率超过0.75,则扩容为原来的2倍)中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的
  2. 不可重复性:保证添加的元素按照equals() 判断时,不能返回true。即:相同的元素只能添加一个
  3. 向Set中添加的数据,其所在的类一定要重写hashCode()和equals()方法:相等的对象必须有相等的散列码(哈希值)

添加元素的过程:以HashSet为例

首先通过散列算法确定元素需添加在数组中的具体位置,如果该位置上有元素了,则比较哈希值,如果哈希值不一样,则该元素以链表的形式添加在该位置,如果哈希值一样,则通过equals()方法比较,如果还是一样则不会添加到集合

  • HashSet:Set接口的主要实现类,线程不安全,可以存储null值

  • LinkedHashSet:作为HashSet的子类,遍历其内部数据时,可以按照添加的顺序遍历

    将数据封装到了Node节点中,对于频繁的遍历操作,LinkedHashSet效率高于HashSet

  • TreeSet:可以按照添加对象的指定属性,进行排序。

    1. 向TreeSet中添加的数据,要求是相同类的对象

    2. 两种排序:自然排序和定制排序

      class User{
          String name;
          int age;
      }
      // 自然排序 需要排序的类需要实现Comparable接口,重写compareTo()方法
      @Override
      public int compareTo(Object o){
          if(o instanceof User){
              User user = (User)o;
              int compare = -this.name.compareTo(user.name);//按照姓名排序
              if(compare != 0){
                  return compare;
              }else{
                  return Integer.compare(this.age,user.age);// 同名再按照年龄排序
              }
          }else{
              throw new RuntimeException("输入的类型不匹配")
          }
      }
      // 自然排序中,比较两个对象是否相同的标准为:compareTO() 返回0,不再是equals().
      
      // 定制排序
      public void test(){
          Comparator<User> com = (o1,o2) -> {
      		if (o1 != null && o2 != null){
      			return Integer.compare(o1.getAge(), o2.getAge());// 按照年龄,年龄一样就不能添加
      		} else {
      			throw new RuntimeException("传参不能为空");
      		}
      	};
      	Set set = new TreeSet(com);
      }
      

2、Map 接口

双列数据,保存具有映射关系“key-value”的集合

Map 中的key:无序的、不可重复的,使用Set存储所有的key ;key所在的类要重写equals() 和 hashCode()

Map 中的value:无序的、可重复的,使用Collection存储所有的value

一个键值对:key-value构成了一个Entry对象。

Map 中的entry:无序的、不可重复的,使用set存储所有的entry

  • HashMap:作为Map的主要实现类;线程不安全,效率高;可存储null的key-value

    // 数组加链表(jdk7)
    // 数组加链表加红黑树(jdk8)
    // HashMap的底层实现原理。以jdk7为例
    HashMap map = new HashMap();// 在实例化以后,创建了长度是16的一维数组 Entry[] table;
    map.put(key1,value1);// 首先调用key1所在类的hashCode()计算key1哈希值,此哈希值经过计算后,得到在Entry数组中存放的位置。
    // 如果此位置上的数据为空,此时key1-value1添加成功。
    // 如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(以链表方式存在)),比较key1和已经存在的一个或多个数据的哈希值:如果key1的哈希值与已存在的数据的哈希值都不相同,此时添加key1-value1成功。如果key1的哈希值和已存在的某一个数据的哈希值相同,继续比较:调用key1所在类的equals()方法,比较,如果equals()返回false,添加成功,如果equals()返回true:使用value1替换相同key的value值,即修改了值
    // 在不断的添加过程中,会涉及扩容问题,默认的扩容方式:扩容为原来容量的2倍,并将原来的数据复制过来。
    
    // jdk8 相较于jdk7在底层实现方面的不同:
    new HashMap(); // 底层没有创建一个长度为16的数组
    // 底层的数组是:Node[] ,而非Entry[]
    // 首次调用put()方法时,底层创建长度为16的数组
    // 数组加链表加红黑树。当某一个索引位置上的元素以链表形式存在的数据个数 > 8 且当前数组长度 > 64时,此索引位置上的所有数据改为使用红黑树存储。
    
  • LinkedHashMap:作为HashMap的子类:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素,对于频繁的遍历操作,执行效率高于HashMap

    // 源码中相较于HashMap
    static class Entry<K,V> extends HashMap.Node<K,V>{
        Entry<K,V> before,after;// 能够记录添加的元素的先后顺序
        Entry(int hash,K key,V value,Node<K,V> next){
            super(hash,key,value,next);
        }
    }
    
  • TreeMap:可按照key对集合进行排序,实现排序遍历。底层使用红黑树

    // 向TreeMap中添加key-value,要求key必须是同一个类创建的对象,因为要按照key进行排序
    // 也是自然排序和定制排序
    
  • HashTable:作为Map的古老实现类;线程安全,效率低;不可存储null的key-value

  • Properties:作为Hashtable的子类,常用于处理配置文件,key和value都是String类型的

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-11 21:59:56  更:2022-03-11 22:03:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:46:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码