java集合

集合:
·数组其实就是一个集合;集合实际上就是一个容器;
·集合通常在实际开发中,用于查询数据库返回的多条数据,然后存放数据库数据比较多;
·集合不能直接存储基本数据类型,也不能存储java对象;
·集合中存储的都是java对象中的内存地址(引用);
·java中每个不同的集合,底层都对应了不同的数据结构;在集合中存储不同的元素,就相当于在不同的数据结构中存储元素,而且每种数据结构存储元素的方式也不同;
例如:数组,二叉树、链表、哈希表,等等;
在java中集合分为两大类:
·一类是以单个方式存储元素;
该类的超级父接口是:java.util.collection;
·一类以键值对的方式存储元素;
该类的超级父接口是:java.util.Map;
collection单个方式存储元素:
List集合存储元素的特点:
·有序的、可重复的,存储的元素有下标,该处的“有序”不是从大到小排序的意思,而是元素存储进入是这个顺序,取出来也是这个顺序;
set集合存储元素的特点:
·无序的、不可重复;该集合中,元素没有下标,元素不可重复,该处的“无序”指的是存元素时是该顺序,但取出来不一定是存进去的顺序;
·可以调用sort()方法进行排序,但对List中的元素进行排序,需要保证List集合中的元素实现了Comparable接口;
List与set集合的特点是相对的;
List下的关系集合:
ArrayList、LinkedList、Vector的区别:
·ArrayList底层代码采用了数组的数据结构,该集合是非线程安全的;
·LinkedList底层代码采用了双向链表的数据结构;
·Vector底层代码采用了数组的数据结构,该集合是线程安全的;但是效率较低;
Set下的关系集合:
·HashList 实际上,底层在new的时候,new的是一个HashMap集合,而往HashList中存储元素,本质上就是在向HashMap集合中存储元素,而HashMap集合是一个哈希表数据结构;
·sortedSet集合存储元素的特点,因为继承了Set集合,所有它的特点也是无序不可重复的,但是放在sortedSet的元素可以自动排序,可成为有序排序,该集合中的元素自动按照大小进行顺序排序;
·SortSet 接口下有个实现类,这个实现类就是TreeSet;
·TreeSet 实际上,底层在new的时候,new的是一个TreeMap集合,而往TreeSet中存储元素,本质上就是在向TreeMap集合中存储元素,TreeMap集合采用了二叉树的数据结构;
Map以键值对的方式存储元素:
·Map集合与Collection集合是没有关系的;
·Map集合以key和value的方式存储元素;
·key和value都是存储java对象的内存地址;
·Map下的两个常用实现类,HashMap和Hashtable;
·所有Map集合,它的特点都是无序不可重复的;
·Map集合的key和set集合存储的特点相同;
HashMap和Hashtable的区别:
·HashMap是非线程安全的,底层采用的是哈希表数据结构;
·Hashtable是线程安全的,底层采用的是哈希表数据结构;因为线程安全,该集合效率较低;
Properties的特点:
·Properties是线程安全的因为继承了Hashtable,另外properties存储元素的时候,也是采用key和value的形式存储,并且key和value只支持String类型的数据,不支持其他类型;
Collection:
在没有使用“泛型”之前,collection可以存储所有object的子类型,
使用了“泛型”之后,collection只能存储某个指定的类型;
注:集合中不能存储基本数据类型,也不能存储java对象,只是存储java对象的内存地址;
Collection中的迭代器,iterator();迭代/遍历;
迭代器是一个对象;
Interator();迭代器中的remove()方法,底层会调equals();只要内容一样,即使内存地址不同,也可以删除;但是前提是equals()必须重写;
集合结构只要发生改变,迭代器必须重新获取;
而且在迭代的过程中,不能调用集合的remove方法;但是可以调用迭代器的remove方法;
简单的说,就是集合中的结构发生改变了,迭代器需要重新获取,而且在迭代时,若想要删除元素,必须使用iterator(迭代器)自带的remove方法;
Collection中的contions和remove方法,底层都会调用equals方法,因此equals方法需要重写;
ArrayList:
·ArrayList初始化的容量为10;(底层先创建了一个长度为0的数组,当添加第一个元素时,初始化容量为10)
·ArrayList底层是一个object[]数组;
·ArrayList集合的扩容:增长到原容量的1.5倍;
·在使用ArrayList集合的底层的数组,数组尽量少扩容,因为效率较低,最后先预估定一个容量值;
·ArrayList集合是非线程安全的;
单向链表:
链表的基本结构是节点(node),对应单向链表来说,任何一个节点node都有两个属性;
第一个属性:存储的数据;
第二个属性:下一个节点的内存地址;(节点的内存地址是不连续的)
链表的优点:
随机增删元素效率较高;(因为增删元素不涉及到大量元素位移)
链表的缺点:
查询效率较低,每次查找某个元素时,都需要从头节点开始遍历;
双向链表(LinkedList):
双向链表的基本单元还是节点node,双向链表有三个属性;
第一个属性:上一个节点的内存地址;
第二个属性:节点元素;
第三个属性:下一个节点的内存地址;
LinkedList集合没有初始化容量;最初链表中没有任何元素,first和last都是null
LinkedList是一个双向链表;链表对于随机增删来说,效率较高;但查找某个元素效率较低;
链表中的(节点)元素在空间内存上,内存地址不连续;
Vector:
Vector底层也是一个数组,初始化容量是10,它是线程安全的;
Vector扩容后的容量,是原容量的2倍;原容量2;
ArrayList集合的扩容容量是:原容量的1.5倍;原容量
1.5;
如何将一个非线程安全的ArrayList集合转换为一个线程安全的集合:
使用集合工具类:java.util.collections;
注意:java.util.collection;是集合接口,
java.util.collections;是集合工具类,不要搞混了;
把一个非线程安全的ArrayList集合转换成一个线程安全的,调用collections下的一个方法synchronizedList();即可;
语法:List myList=new ArrayList();
引入java.util.collections包;
Collections.synchronizedList(myList); //这样就可以将一个非线程安全的集合转换成一个线程安全的集合;
泛型机制:
泛型机制是jdk5.0之后推出的新特性;
使用泛型后,集合中,只能存储指定的元素类型;
泛型属性编译阶段的一个新特性,在运行时阶段,没什么用处;
泛型的优点:
使用泛型之后,集合中,在获取元素时,不需要进行过多的“向下转型”;
泛型的缺点:
使用泛型之后,集合中存储的元素相对单一,缺乏多样性;
但是泛型在调用子类特有的方法时,还是需要进行“向下转型”的;
自动类型推断机制(钻石表达式):
自动类型推断机制是jdk8之后才有的新特性;
Jdk8之前:List myList=new ArrayList();
Jdk8之后:List myList=new ArrayList<>();
Map集合:
使用时,需要引用java.util.Map;包
Map和Collection是没有继承关系的;
Map的存储数据方式是以key和value的方式存储数据,键值对的方式;
Key和vakue都是引用数据类型;
Key和value都是存储对象的内存地址;
key起到一个主导地位,而value是key的一个附属品;
Map中有一个Set<Map.Entry<K,Y>> entrySet();方法;
Map集合通过entrySet()方法转换为这个Set集合,Set集合中,元素的类型是Map.Entry,Map.Entry其实是一个类,一个静态内部类,和String差不多;是Map中的一个内部类;
(HashMap)哈希表数据结构:
HahsMap底层是一个哈希表/散列表的数据结构;是非线程安全的;
哈希表是一个数组和单向链表的结合体;它结合了数组与单向链表的优点;
HashMap实际上,可以理解为是一个一维数组,然后数组中的每一个元素是一个单向链表;
Map.put(k,v)的添加元素实现原理:
第一步:先将k,y封装到node的对象中;
第二步:底层会调用hashCode()的方法得出hash值,然后通过哈希函数/哈希算法,将hash值转换成数组的下标,下标位置上如果没有任何元素,则会将node添加到这个位置上,如果下标对应的位置上有链表,此时会拿着k和链表中所有的k进行equals对比,如果所有对比后的结果是false,那么这个新节点则会添加到链表的末尾,如果有其中一个k返回的结果是true,那么就会把原先相同的那个k,把该k中的value值覆盖掉/替换掉;
Map.get(k)的获取元素实现原理:
先调用k的hashCode()方法得出哈希值,通过哈希算法将哈希值转换成数组下标,然后通过数组下标快速定位到某个位置上,如果这个位置上什么都没有,则会返回null,如果这个位置上有链表,则会拿着参数k与链表中的所有k,调用equals()方法进行对比,如果equals()方法返回false,那么get()方法也就返回null,如果equals()返回的是true,
此时就会把返回为true的这个k给到get()方法,而get()方法最终就返回要找的这个value;
HashMap集合的初始容量是16,默认加载因子是0.75,也就是当集合底层的数组容量达到75%的时候,数组开始扩容;
注意:HashMap的初始容量必须是2的倍数,这也是官方推荐的,因为可以达到散列分布均匀,为了提高HashMap集合的存取效率,所必须的;扩容后是原容量的2倍;
在jdk8之后,如果单向链表中元素超过8个,单向链表数据结构会自动变成红黑树数据结构,当红黑树的节点数量小于6时,红黑树数据结构会自动变回单向链表数据结构;
Hashtable集合:
该集合是线程安全的,但hashtable对线程安全处理效率较低,使用较少;
Hashtable和HashMap一样,底层都是哈希表数据结构;
该集合的初始容量是11,默认加载因子是0.75f;扩容后的容量是:原容量*2+1;
Properties集合:
Properties是一个集合,继承Hashtable,properties的key和value都是String类型;properties被称为属性类对象;
自平衡二叉树:
自平衡二叉树遵循的是左小右大的原则存放;
前序遍历:根左右;
中序遍历:左根右;
后序遍历:左右根;
注意:中前后说的是“根”的位置;根在前面是前序,根在中间是中序,根在后是后序;
TreeSet/TreeMap集合:
TreeSet/TreeMap集合采用的是中序遍历方式,Iterator迭代器采用的是中序遍历方式,左根右;
Comparable和Comparator如何选择:
当比较规则不会发生改变时,或者比较规则只有一个时,建议选择使用Comparable接口;
如果比较规则有多个,并且多个比较规则频繁切换的时候,建议选择使用Comparator接口;Comparator接口设计符合OCP原则;
Collections工具类:
Collection和Collections不同;
Collection是集合接口;
Collections是集合工具类,方便集合的操作;
Collections中有一个方法,synchronizedList()方法可以将非线程安全的转变成线程安全;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值