Java集合框架总结

在这里插入图片描述

  • 最顶层接口

Collection:存储单个值
Map:存储键值对 key-value

  • Collection的子接口

List:可以存储重复数据、可以存储null值、插入有序
Set:不可存储重复数据、可以存储null值、插入无序
Queue:不可存储重复数据、不可存储null值、插入无序

  • List接口的主要实现类

ArrayList:底层结构为数组 ,查询效率高(下标)、修改效率低
LinkedList:底层结构为双向链表,查询效率低、修改效率高

  • ArrayList的使用
public class ArrayListDemo {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList1 = new ArrayList<>();
        arrayList1.add(45);//添加指定类型 boolean add(E e)
        arrayList1.add(34);
        arrayList1.add(55);
        arrayList1.add(55);
        arrayList1.add(2);

        ArrayList<Integer> arrayList2 = new ArrayList<>();
        arrayList2.add(55);
        arrayList2.add(3);

        arrayList1.removeAll(arrayList2);//差集,删除给定集合的元素
        arrayList1.retainAll(arrayList2);//交集,不同对象调此方法结果不同
        arrayList1.removeAll(arrayList2);
        arrayList1.addAll(arrayList2);//不重复并集

        Integer[] array = (Integer[])arrayList1.toArray();//集合转化为数组
        arrayList1.contains(55);//检查是否存在给定元素
        arrayList1.remove(Integer.valueOf(55));//remove() 两种删除方式:下标、对象
        arrayList1.set(0,34);//set() 修改 返回下标为index的原存储值

        Iterator<Integer> iterator = arrayList1.iterator();//创建迭代器实例(通过集合对象调用iterator()方法)
        //访问集合
        while (iterator.hasNext()){//判断集合是否还能继续遍历
            Integer value = iterator.next();//获取元素
            System.out.println(value);
        }
        for (Integer i:arrayList1) {//for each遍历方式底层实现方式迭代器
            System.out.println(i);
        }

        for (int i = 0; i < arrayList1.size(); i++) {//size() 统计集合元素个数
            System.out.println(arrayList1.get(i));//get() 获取元素
        }
    }
}
  • 迭代器

是一种设计模式,提供了一种方法来访问容器(集合)
迭代器的使用(具体可以看ArrayList的使用):
1、创建迭代器实例(通过集合对象调用iterator()方法)
2、判断集合是否还能继续遍历
3、获取元素
迭代器的特点:
1、数据的遍历从前往后
2、hasNext()和next()要交替使用

  • LinkedListd的使用
public class LinkedListDemo {
    public static void main(String[] args) {
        LinkedList<Integer> linkedList = new LinkedList<>();
        linkedList.add(13);
        linkedList.add(11);
        linkedList.add(45);
        linkedList.add(1);
        linkedList.offer(2);//添加元素

        linkedList.get(1);
        linkedList.element();//获取队头元素即第一个元素
        linkedList.peek();//获取队头元素即第一个元素

        linkedList.remove(11);//若不传参数则删除第一个元素
        linkedList.pop();//删除队头元素即第一个元素
        linkedList.poll();//删除队头元素即第一个元素

        linkedList.indexOf(13);//找到元素在集合中的位置
        linkedList.toArray();//转成数组
        linkedList.subList(1,2);//截取指定范围的子集合
    }
}

适用场景
查询操作多的场景下使用ArrayList
变更(插入、删除) 多的场景下使用LinkedList
不同点
1.ArrayList需要扩容(1.5倍扩容),LinkedList不需要扩容
2.*ArrayList底层数据结构为数组,LinkedList底层数据结构为双向链表
3. *ArrayList查找效率高,LinkedList插入和删除效率高
4. LinkedList实现Deque接口,提供了头插尾插头删尾删等方法
5. ArrayList有默认值10,LinkedList没有默认值
相同点
1.可以存放重复性数据、可以存储null值、插入有序
2.可以实现克隆和序列化
3.都可以使用ListIterator迭代器

  • Map接口

哈希结构:通过关键码(key)找到值(value)的结构,底层数组,对数据的访问通过哈希函数(键和值的映射关系)
哈希函数:好的哈希函数能够使值均匀地分布在哈希结构中
两种生成哈希函数方式:①直接寻址法 f(x) = kx + b(k和b是常数)
②除留余数法 f(x) = x mod m(m是常数,一般取素数或哈希长度,m<=哈希长度)
哈希冲突:当通过哈希函数计算出来的值总会有相同情况,此时映射到数组的同一位置,即产生了哈希冲突
两种哈希冲突的解决方式:①链地址法 ②线性探测法

  • HashMap的使用
public class HashMapDemo {
    public static void main(String[] args) {
        HashMap<String, String> hashMap = new HashMap<>();
        //添加元素
        hashMap.put("黄晓明", "杨颖");
        hashMap.put("邓超", "孙俪");
        hashMap.put("黄磊", "孙莉");
        /**
         * key插入无序
         * key不能重复,value可以重复
         * 当插入的键值对中的key和集合中的key相同时,会覆盖掉之前的值
         * key可以为null,value可以为null
         */

        //map三种遍历方式
        System.out.println("通过键值对遍历:");
        Iterator<Map.Entry<String, String>> iterator = hashMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + ":" + value);
        }
        System.out.println();
        System.out.println("通过键遍历:");
        Iterator<String> iterator1 = hashMap.keySet().iterator();
        while (iterator1.hasNext()){
            System.out.println(iterator1.next());
        }
        System.out.println();
        System.out.println("通过值遍历:");
        Iterator<String> iterator2 = hashMap.values().iterator();
        while (iterator2.hasNext()){
            System.out.println(iterator2.next());
        }
    }
}

不同点
1.继承的父类不同,因此特有的方法不同
Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。
2.线程安全不同
HashMap是线程不安全的, Hashtable中每个方法都加了synchronized关键字,因此是线程安全的。
HashMap实现线程安全:Collections.synchronizedMap(hashMap);
3.key和value是否允许null值
HashMap中的key和value都允许为null,key只允许一个null值,Hashtable不允许key和value为null。
4.hash函数与索引的计算方式不同
( hashCode是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值)
Hashtable的hashSeed与hashCode进行异或操作计算hash值,而HashMap使用hashCode进行一系列异或操作计算出hash值。
Hashtable在求hash值对应的位置索引时,用取模运算,而HashMap在求位置索引时,用与运算。
5.数组初始化容量不同
Hashtable在不指定容量的情况下的默认容量为11,而HashMap为16。Hashtable不要求数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。
6.扩容机制不同
Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。
7.迭代方式
HashMap只有迭代器,Hashtable可以使用迭代器、枚举遍历方式
8.效率不同
单线程下HashMap效率比Hashtable高

相同点
1.实现接口:实现Map接口,可克隆,可序列化
2.迭代器:使用Iterator迭代器
3.存储结构:使用哈希表存储
4.重复性:key不能重复,value值可以重复

  • HashSet特点

基于HashMap实现、可以存储null值、数据插入无序、数据不可重复
因事先Set接口,则存储单个值,为HashMap中的key,因此插入无序

public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }//add方法没有使用value,因此存储单个值而不是键值对

适用场景:数据去重(插入无序)

  • LinkedHashMap特点
    继承自HashMap,但数据插入有序(Entry节点添加了两个属性after、before,底层实现双向循环链表),其他与HashMap基本一样

  • LinkedHashSet特点

继承自HashSet,插入有序,存储单个值,数据不能重复,可以存储null值

//HashSet的构造函数之一
//没有访问修饰符,不能被直接调用,即专门为LinkedHashSet提供的
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }//底层调用LinkedHashMap

适用场景:数据去重(插入有序)

  • TreeMap特点

数据按照特定规则排序,底层实现是红黑树,实现Comparator接口,key不能为null
要想按照自习的方式排序需写一个比较器作为参数传入

  • TreeSet特点与适用场景

底层实现TreeMap,存储单个值,不能存储null值(因为需要比较),不能重复,按照给定规则排序
适用场景:数据去重,按照特定规则排序

  • Queue接口的实现类:PriorityQueue

队头元素总是最小元素(若想得到最大元素需写一个比较器作为参数传入)
特点:不能存储null值,数据可以重复

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值