collection中的List、Map、Set存储结构解析

本文详细介绍了Java集合框架中的List接口实现,包括Vector、ArrayList和LinkedList的特点与区别,以及Set中的HashSet。同时,讨论了HashMap和Hashtable在存储结构和线程安全性上的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

List详解

Collection是所有集合的父类,其中包含了List、Map、Set三个接口。如图1.0所示
在这里插入图片描述
图1.0.集合的继承关系

List接口的实现

Vector

vetor与数组类似有一段连续的存储,拥有一段连续的内存空间,

随机存取

自动分配工作空间节省空间

但是插入速度较慢,只能在尾部插入,在头部插入或者删除的时候消耗时间规模与容器的大小成正比

当数组内存空间不够时,会重新申请一块内动空间并进行内存拷贝。进行整体的分配的拷贝与释放。

/*
 * Vector数据存储
 */
public class vector {
	   
	        public static void main(String[] args) {
	            Vector v=new Vector<>();
	            //void addElement(E obj) 将指定的组件添加到此向量的末尾,将其大小增加 1。 
	            v.addElement("hello");
	            v.addElement("world");
	            v.addElement("java");

	            for(int x=0;x<v.size();x++){
	            	//E elementAt(int index) 返回指定索引处的组件。
	                String s=(String) v.elementAt(x);
	                System.out.println(s);
	            }
	       	    }
}

Arraylist

ArrayList是非同步的是线程不安全的

同Vector一样是一个基于数组上的链表,但是不同的是ArrayList不是同步的。所以在性能上要比Vector好一些,但是当运行到多线程环境中时,可需要自己在管理线程的同步问题。ArrayList是实现了基于动态数组的数据结构

ArrayList是线程不安全的因为线程的同步必然会影响线程的执行效率所以ArrayList的性能相对的比Vector好一些

当内存空间不足的时候ArrayList会增加初始容量的50%,这样有利于节约内存空间。

集合的嵌套:
多种不同ArrayList的遍历,将不同的ArrayList放置于大的ArrayList集合中

	/*
	*ArrayList存储
	*/
public class ArrayListDemo {
	
	    public static void main(String[] args) {
	        ArrayList<ArrayList<Student>> bigArrayList=new ArrayList<ArrayList<Student>>();

	        //子集合一
	        ArrayList<Student> firstArrayList=new ArrayList<Student>();

	        Student s1=new Student("宋江", 30);
	        Student s2=new Student("武松", 29);
	        Student s3=new Student("鲁智深", 28);
	        Student s4=new Student("李逵", 27);
	       
	        firstArrayList.add(s1);
	        firstArrayList.add(s2);
	        firstArrayList.add(s3);
	        firstArrayList.add(s4);
	        
	        bigArrayList.add(firstArrayList);

LinkedList

LinkedList基于双向链表实现,因此不像ArrayList需要扩容机制。
当ArrayList扩容时,会自动生成一个新的array(长度是之前的1.5倍),再将旧的array移值上去,不存在容量不足现象。
由于LinkedList实现了Deque,而Deque接口定义了在双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。
LinkedList可以作为FIFO(先进先出)的队列或者LIFO(后进先出)的栈
LinkedList也是线程不安全的

/*
*LinkedList存储
*/
public class LinkedList {
    public static void main(String[] args) {
        LinkedList link=new LinkedList<>();

        link.add("hello");
        link.add("world");
        link.add("java");

		//将指定的元素插入到列表的开头
        link.addFirst("say weizhao");
        //将指定的元素插入到列表的结尾
        link.addLast("last");

		//移除并返回此列表的第一个元素
        link.removeFirst();
        //移除并返回此列表的最后一个元素
        link.removeLast();

        System.out.println("link:"+link);
		//返回第一个/最后一个元素
        System.out.println("link.getFirst="+link.getFirst());
        System.out.println("link.getLast="+link.getLast());
    }
}

LinkedList和ArrayList的区别

1、ArrayList继承于 AbstractList, LinkedList继承于 AbstractSequentialList;
2、ArrayList基于动态数组的数据结构, LinkedList基于双向链表。
3、对于随机访问, ArrayList比较占优势,LinkedList插入、删除元素比较快,如果只要调整指针的指向那么时间复杂度是O(1), 但是如果针对特定位置需要遍历时,时间复杂度是O(n),也就是LinkedList在随机访问元素的话比较慢;
4、LinkedList需要更多的内存,因为 ArrayList的每个索引的位置是实际的数据,而 LinkedList中的每个节点中存储的是实际的数据和前后节点的位置;
5、ArrayList 和 LinkedList都是非同步的集合,都是线程不安全的
6、Linked基于链表因此不需要ArrayList的扩容机制

Set

HashSet

/*
*HashMap存储
*/
public class HashSetDemo {
    public static void main(String[] args) {
        HashSet<Like> hs=new HashSet<Like>();

        Like s1=new Like("唱",1);
        Like s2=new Like("跳", 2);
        Like s3=new Like("rap", 3);
        Like s4=new Like("篮球", 4);
        Like s5=new Like("美妆", 5);
        

        hs.add(s1);
        hs.add(s2);
        hs.add(s3);
        hs.add(s4);
        hs.add(s5);
      

        for(Like s:hs){
            System.out.println(s.toString());
        }
    }
}

定义Like类

/*
*必须同时重写hashCode()和equals()两个方法,才能使相同属性的对象具有相同哈希值。
*/
 public class Like implements Comparable<Like>{
	        private String name;
	        private int weight;
	        public Like() {
	            super();
	        }
	        public Like(String name, int weight) {
	            super();
	            this.name = name;
	            this.weight = weight;
	        }

	        public String getName() {
	            return name;
	        }
	        public void setName(String name) {
	            this.name = name;
	        }
	        public int getweight() {
	            return weight;
	        }
	        public void setweight(int weight) {
	            this.weight = weight;
	        }

	        public String toString() {
	            return "Like [name=" + name + ", weight=" + weight + "]";
	        }

	        //实现LinkedHashSet排序,必须同时重写hashCode()和equals()两个方法,才能使相同属性的对象具有相同哈希值
	        @Override
	        public int hashCode() {
	            final int prime = 31;
	            int result = 1;
	            result = prime * result + weight;
	            result = prime * result + ((name == null) ? 0 : name.hashCode());
	            return result;
	        }
	        @Override
	        public boolean equals(Object obj) {
	            if (this == obj)
	                return true;
	            if (obj == null)
	                return false;
	            if (getClass() != obj.getClass())
	                return false;
	            Like other = (Like) obj;
	            if (weight != other.weight)
	                return false;
	            if (name == null) {
	                if (other.name != null)
	                    return false;
	            } else if (!name.equals(other.name))
	                return false;
	            return true;
	        }
	        
	    }

Map

HashMap和Hashtable的区别

hashMap(数组+链表+红黑树)和Hashtable(链表)的区别:

  1. 两者继承的类不同,两者都实现了Map接口,但是HashMap继承的是AbstractMap,而Hashtable继承的是Dictionary

  2. HashMap中的方法都是非同步的而Hashtable中的方法是同步的,所以HashMap是线程不安全的,Hashtable是线程安全的。在单线程中,HashMap的执行效率却是比Hashtable高

  3. HashMap中的put方法允许键值对为空,而Hashtable不可以
    Hashtable:底层是vector ,vector中的元素是链表
    Vector 代表篮子,初始大小是53当数据超过长度的时候会变大2倍。存节点指针时会经过hash函数找到对应的篮子,然后连在篮子后面 当扩容的时候以前存入的元素会重新分配篮子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值