Java中的集合(2)——深谈集合间的区别

在上篇文章当中我们主要介绍了java中集合的定义,分类以及各个类型集合对应的实现类。本篇文章我就来为大家梳理一下Java中各类型集合之间的区别。

(创作不易,请各位读者大大点赞评论关注😊)

一、关于集合的介绍

  1. 集合它是类似于数组一样的容器,但是比数组在操作数据上更加方便、灵活,可以使用一个集合存放各种类型的数据,在jdk 1.5 版本新增泛型的概念。用泛型来规范集合关于数据的储存。
  2. 集合在进行数据储存时能够实现自动扩容,还提供了快速进行数据增删改查的操作方法;
  3. 根据储存数据的方式将集合分为单列集合和双列集合:
  4. 单列集合最顶层的接口为 Collection ,双列集合最顶层的接口 Map
  5. Collection 下有很多的子接口,最具有的代表性的接口 List Set
  6. Map 下常用的实现类为 HashMap

二、单列集合顶层Collection和双列集合顶层Map的区别

                                       注:(蓝色字体为精要总结,便于记忆)

Collection 是所有 单列集合最顶层的接口 ,它继承了 Iterable 接口,证明 Collection 下面所有的
子接口和子接口实现类都 能够使用迭代器进行遍历
Collection 没有直接的实现类,所有的实现 都需要使用其子接口的实现类
Collection 无构造方法,不能直接创建对象,它创建对象的方式 需要使用多态 (父接口引用实现类对象) Collection c = new ArrayList();
1、遍历方法不同
Collection遍历集合的方法:
①.使用 迭代器 iterator() 进行遍历           (interator可能会出现迭代器使用异常,后续会继续讲解)
        Iterator iterator = c.iterator();
        while(iterator.hasNext()){
            Object next = iterator.next();
            System.out.println(next);
        }

②.增强 for 循环遍历

    for(Object obj:c){
        System.out.println(obj);
    }
Map 是双列集合最顶层的接口,没有像单列集合一样实现 Iterable 接口,因此 Map 集合 不支持迭代器进行遍历
①. entrySet() 方法遍历
public void test_map(){
Map<String,String> map = new HashMap();
map.put("西游记","吴承恩");
map.put("红楼梦","曹雪芹");
map.put("三国演义","罗贯中");
map.put("水浒传","施耐庵");
Set<Map.Entry<String, String>> entries = map.entrySet();
for(Map.Entry<String, String> entry : entries){
    System.out.println(entry.getKey() +"-----"+entry.getValue());
    }
}

②.keySet() 方法

public void test_map(){
Map<String,String> map = new HashMap();
map.put("西游记","吴承恩");
map.put("红楼梦","曹雪芹");
map.put("三国演义","罗贯中");
map.put("水浒传","施耐庵");
Set<String> keys = map.keySet();
for(String key : keys){
    System.out.println(key + "-----" + map.get(key));
    }
}

2、数据存放要求不同
Collection下面的 List 集合且 允许元素重复储存且有序;
Collection下面的 Set 集合 元素无序、不重复集合 ;常用的实现类是 HashSet TreeSet ;其中 TreeSet 能够实现内部元素( jdk 预定义类型)的排序,默认使用自然排序,还 可以自定义排序规则 HashSet 实现类不保证添加元素和遍历元素的顺序, 允许存在 null 元素,但只能有一个 :HashSet 去重原理需要牢牢掌握哦! 默认使用 Object hashCode 方法和 equals 方法实现去重   treeset不能存储null。
Map 集合进行元素存放时,要求元素对象是一个 key = value 的一组键值对映射关系( Entry ),其中 key 值不允许出现重复项,value 可以有重复的;
HashMap Map 接口最常用的实现类, 允许出现 null 健和值,但是健只能有一个是 null,值可以有多个为 null。
Hashtable 不允许有 null 健和 null 值
3、底层原理和扩容机制不同
  • ArrayList 底层是由数组实现的,所以它的特性为查找元素效率高,插入元素效率低;默认的初始容量为 10,在进行元素添加时会先判断容量是否足够,不足时系统会自动进行扩容;int newCapacity = oldCapacity + (oldCapacity >> 1); 即是容量变为原来的 1.5 倍
  • LinkedList因为底层由双向链表实现,因此它的插入效率高,查询效率低
  • HashSet 实现类 底层由数组+链表(可变红黑树)实现;通常使用空参构造进行对象的创建,创建的数组初始容量为 16负载因子 0.75;当数组的储存数据达到 16*0.75 = 12 时,系统就会就行自动扩容,容量变为以前2倍
  • TreeSet 底层有 TreeMap 实现,使用 排序树 (红黑树)的结构实现数据的储存,会对内部数据进行自然排序(升序);
  • HashMap 底层由 哈希表(数组+链表,链表可变为红黑树) 实现数据的储存; 数组的 初始容量为 16 负载因子 0.75 ,当储存的数据量达到 16*0.75 = 12 (阈值) 时,会自动进行数组的扩容, 扩容为原来的 2 倍;最大扩容到 64 当容量变为 64 时,如果某个位置上链表长度达到 8,此时链表就会自动转换为红黑树 ;如果再对红黑树中的结点进行删除使结点个数少于 8 时,红黑树又会自动变为链表;
  • LinkedHashMap 具备 HashMap 的一切功能,再此基础上还提供一个双向链表来维护元素添加的先后顺序,先添加的元素在链表的前面,后添加的在链表后面;
  • Hashtable 底层也是由 数组+链表 的方式实现数据储存,默认初始容 量为 11 ,负载因子 0.75 ;自动扩容的机制为: int newCapacity = ( oldCapacity << 1 ) + 1 ;
4、线程安全性不同
List集合ArrayList和LinkedList 都是线程不安全的,Vector是线程安全的;
Set集合 中的HashSet、TreeSet、LinkedHashSet都是线程不安全的。如果要用线程安全的set集合,可以使用java.util.concurrent包中提供的线程安全的set集合;
Map集合中HashMap、TreeMap是线程不安全的。Hashtable是线程安全的。
5、红黑树补充
红黑树是 二叉树 中一种特殊结构,具备一些特性:
性质 1. 结点是红色或黑色。
性质 2. 根结点是黑色
性质 3. 所有叶子都是黑色 。(叶子是 NIL 结点)
性质 4. 每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上 不能有两个连续的红色结点
性质 5. 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点
性质 6. 红黑树能够实现自平衡,当左子树和右子树的深度差超过 1 时,红黑树会自动进行结点的旋转,让左
子树和右子树的深度差小于等于 1 ,旋转后再改变结点的颜色;
性质 7 :红黑树能够自动进行结点元素的排序操作,每一个结点左边的结点值都比它小,每一个结点右边的结点
值都比它大
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值