Java~数据结构(一)~集合框架学习和背后的数据结构

30 篇文章 4 订阅
7 篇文章 1 订阅

Java集合框架

Java集合框架又称为Java Collection Framework.可以认为是容器。定义在java.util包下的一组接口和其实现类。

  • 集合就是存放数据的容器。方便对数据进行CRUD
  • JAVA集合类都是由Collection和Map集合类派生出来的
  • Collection派生出List、Set、Queue子类。如下图
    在这里插入图片描述

集合与数组的区别:

  • 数组只能保存固定且不具有映射关系的数据。集合可以保存不定数量和具有映射关系的数据。
  • 数组可以保存基本类型数据,也可以保存引用类型数据。而集合只能保存对象。(基本类型数据都是放入包装类)

Collection派生的三个集合-List、Set、Queue

List集合

List集合中的元素排列有序,并且可以重复。List包含三个常用子类:ArrayList、LinkedList、Vector.(Vector已弃用)

ArrayList
  • 底层实现是数组。
  • 元素按顺序排列,所以可以重复
  • 按照下标查找元素、所以查询快,增删需要移动元素位置,所以增删慢
  • 非线程安全
  • 结构如下图:

在这里插入图片描述

  • 使用注意:在使用ArrayList时,如果提前知道要放入元素的长度,并且提前指定集合长度,可以减少时间消耗。提高性能。
 public static void main(String[] args) {
        long data_one=System.currentTimeMillis();
        //未指定长度
        ArrayList<Integer> list=new ArrayList<Integer>();
        for(int i=0;i<100000000;i++){
            list.add(i);
        }
        System.out.println(System.currentTimeMillis()-data_one);  // 不指定容量用时:66929
        
        long data_two=System.currentTimeMillis();
        ArrayList<Integer> list_s=new ArrayList<Integer>(100000001);
        for(int i=0;i<100000001;i++){
            list_s.add(i);
        }
        System.out.println(System.currentTimeMillis()-data_two);// 指定容量用时:45963
    }
LinkedList
  • 底层使用双向链表
  • 因为根据链表查找元素,所以查找慢。增删只需要替换对应节点指针,所以增删快
  • 元素按照插入顺序排列,可以重复
  • 结构如下图:
    在这里插入图片描述

Set集合

Set集合是一组无序不可重复的集合。(LinkedHashSet有序)。包含三个常用的子类:HashSet、TreeSet、LinkedHashSet。

HashSet
  • 底层用HashMap数据结构实现。放入的元素存为Key,不关心value.所以value和Key是同一个对象。key元素可以为null
  • 因为HashMap中的Key不可重复,而在HashSet我们只关心key,所以HashSet中的元素也认为不可以重复、并且无序
  • 内部使用HashMap的数据结构,并没有自身的数据结构。HashMap结构在 JDK1.8中添加了红黑树。内部节点代码如下:
static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;
        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }
 }
 
  • HashMap的结构是数组加链表的形式。如下图:
    在这里插入图片描述
TreeSet
  • 内部数据结构用TreeMap实现,底层采用树结构来进行存储元素
  • 元素按照字符串顺序存储,不允许为null
LinkedHashSet
  • 继承自HashSet,内部采用的是LinkedHashMap的数据结构
  • 因为继承自HashSet,所以和HashSet相同,元素不可重复。但是元素有序
  • 因为用LinkedHashMap数据结构实现,而LinkedHashMap中用LinkedHashMapEntry来存储元素,源码如下:
static class LinkedHashMapEntry<K,V> extends HashMap.Node<K,V> {
    LinkedHashMapEntry<K,V> before, after;
    LinkedHashMapEntry(int hash, K key, V value, Node<K,V> next) {
        super(hash, key, value, next);
    }
}

  • 可以看出LinkedHashMapEntry继承了Node节点,并且添加了before\after两个指针。这样就保证了元素顺序。
    在这里插入图片描述

Queue队列

Queue集合不是文章重点。本文主要是了解Java集合框架。Queue会在其他文章中介绍。

Collection集合本身的常用方法

public static void main(String[] args) {
        Collection<String> list=new ArrayList<>();
        System.out.println("现在Collection集合的长度是:"+list.size());
        System.out.println("集合是否为空:"+list.isEmpty());
        list.add("c");//添加元素
        list.add("b");
        list.add("a");
        System.out.println("现在集合的长度是:"+list.size());//得到集合长度
        System.out.println("集合现在是否为空:"+list.isEmpty());//判断是否为空
        System.out.println("集合中现有的元素有:");
        for(String s:list){
            System.out.print(" "+s);
        }
        list.remove("a");//删除指定元素的第一个出现。如果存在。
        System.out.println(" ");
        System.out.println("集合中现有的元素有:");
        for(String s:list){
            System.out.print(" "+s);
        }
        list.removeAll(list);//清空整个集合  clear方法也是如此
        System.out.println(" ");
        System.out.println("集合现在是否为空:"+list.isEmpty());
    }

每个集合接口具体用什么数据结构实现的?

在这里插入图片描述

  • Set接口:用红黑树实现了TreeSet,用哈希表实现了HashSet
  • List接口:用数组实现了ArrayList,用链表实现了LinkedList
  • Queue接口:用堆实现了PriorityQueue(优先级队列)。
  • Map接口:用红黑树实现了TreeMap,用哈希表实现了HashMap。

Map集合

  • 具有<key,value>映射关系的元素。有以下几个常用的实现类:HashMap,LinkedHashMap,HashTable,TreeMap。

HashMap

  • HashSet的实现使用了这个数据结构。
  • HashMap中通过key 进行hashCode()相关的位运算得到数组中的位置索引。如果hash散列算法以及数组长度合适的话,效率很高。
  • 可以为null,可以存入键为null的键值对
  • 线程不安全,在高并发的环境下HashMap容易出现死循环。所以多线程环境中可以使用Collections.synchronizedMap()或者HashTable。这两个是线程安全的。但是HashTable是对方法整体加锁,而Collections.synchronizedMap()是对代码块加锁,所以效率不够高。
  • 高并发环境下可以使用ConcurrentHashMap,它采用是分段加锁。
  • HashMap结构上面已经展示过了。

LinkedHashMap

  • 这个类是HashMap的子类。和HashMap的区别就是在HashMap的基础上,增加了一个双向链表来记录存储数据的先后顺序。这样保证在遍历数据时候,首先得到的是先插入的数据。
  • 结构如下:
    在这里插入图片描述

HashTable

  • 不允许存入键值为null。key和value都不可以为null,否则会报NullPointerException.
  • 这个类是线程安全的,但是因为对方法整体加锁,所以并发性很差,效率不高。如果对线程安全没有要求,一般使用HashMap,如果有要求,一般使用ConcurrentHashMap。
  • 结构和HashMap一样。

TreeMap

  • 实现了SortedMap接口。从源码中看到,key必须实现Comparable接口或者在构造TreeMap传入自定义的Comparator,否则运行时会抛出异常
  • 可以将保存的数据根据键排序,默认是按照键值升序排序,可以在构造方法中指定排序使用的比较器。

常见笔试及面试题

1.HashMap了解不,介绍一下,如果一个对象为Key时,hashCode和equals方法的用法要注意什么
2.HashMap和HashSet的区别是什么?
3.HashMap是线程安全的吗?如果是,为什么?如果不是,那需要用什么?
4.ArrayList 和LinkedList 的区别是什么
5. 有了解过HashMap的具体实现吗
6. HashMap和ConcurrentHashMap那个效率高
7.hashCode主要是用来做什么的?

配图链接:https://blog.csdn.net/oman001/article/details/104843676?spm=1001.2014.3001.5506

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值