Java笔记-集合框架

参考:Java集合框架最全详解(看这篇就够了)
Java容器

1、Java集合框架体系图

在这里插入图片描述
Java集合类主要由两个根接口Collection和Map派生出来的。

2、Collection

Collection是单列集合,派生出List、Set、Queue
在这里插入图片描述

(1)List

List的实现类:

  • **ArrayList:**有序、可重复
    a.是一个动态数组object[10](初始容量10),可以插入任何符合规则的元素以及null,查询快
    b.当数组元素到达一半时,会进行扩容为原来的1.5倍。因此当明确元素有多少时,可以指定初始容量值,避免多次扩容浪费时间和效率
    c.线程不安全,效率高
    d.ArrayList擅长于随机访问,同时ArrayList是非同步的。
  • LinkedList
    a.采用双向循环链表实现(Node{first,last}),实现了List和Deque接口,可以作为双端队列使用(可以做栈,也可以做队列)。插入、删除效率高
    b.线程不安全,效率高
  • Vector
    a.动态数组object[10],查询快
    b.当数组元素满了之后,扩容为原来的2倍
    c.线程安全,效率低
    d.与ArrayList相似,但是Vector是同步的,它的操作与ArrayList几乎一样
    在这里插入图片描述

获取线程安全的List

(1)Vector:同步,效率低,开销大
(2)Collections.synchronizedList(list)
(3)JUC包下的CopyOnWriteArrayList<>()
读写分离:写操作在一个复制的数组中进行,读操作在原数组进行,互不影响
写时复制:写操作加锁,防止并发写入导致写入的数据丢失。写操作结束后,将原始数组执行复制数组

List<String> list=new CopyOnWriteArrayList<>();

(2)Set-

Set的实现类:

  • HashSet: 无序、元素不可重复
    a.底层实现是HashMap,可以存储null,查找快
    b.底层数据结构是数组+链表 + 红黑树
    c.线程不安全
    d.通过equals和HashCode来判断两个元素是否相等
  • LinkedHashSet: 有序(添加顺序)、元素不可重复
    a.继承HashSet,本质是LinkedHashMap实现.可以存null
    b.底层数据结构由哈希表(是一个元素为链表的数组)和双向链表组成
    c.有序的, 根据HashCode的值来决定元素的存储位置,同时使用一个链表来维护元素的插入顺序
    d.线程不安全
    e.添加元素是类对象时,要求类重写hashcode和equals
  • TreeSet: 有序(自然排序)、元素不可重复
    a.实现了SortedSet接口,底层是用TreeMap实现的.正常情况下不能有null值可以重写Comparable接口 局可以有null值了。
    b.本质上是一个红黑树
    c.排序:自然排序(存储元素实现Comparable接口)和定制排序(创建TreeSet时,传递一个自己实现的Comparator对象,按照指定属性排序)

(3)Queue-队列集合

在这里插入图片描述
队列特点:FIFO(先进先出),尾部添加,头部删除

  • Deque双端队列

a.Deque接口是Queue接口的子接口
b.当程序中需要使用“栈”这种数据结构时,推荐使用ArrayDeque。

  • PriorityQueue
    a.保存队列元素的顺序并不是按照加入的顺序,而是按照队列元素的大小进行排序
    b.允许插入null元素

3.Map

Map是双列集合,存储key-value键值对(key不能重复)。可以根据key访问value元素
Map派生出HashMap 、LinkedHashMap、TreeMap、HashTable、Properties
在这里插入图片描述

(1)HashMap

  • 数据结构是数组+链表+红黑树(JDK8),根据hashCode存储数据,访问速度快,无序.
  • 扩容:有索引的链表长度大于8且数组长度大于64时,转为红黑树
  • 线程不安全,效率高。可以用 Collections的synchronizedMap方法使HashMap具有线程安全的能力**(效率低)**,或者使用ConcurrentHashMap类。
  • 最多允许一个key为null,允许多个value为null
  • HashMap map=new HashMap();JDK8在底层没有创建长度为16的Node[],而是在首次调用put时,创建容量为16的数组

HashMap为啥线程不安全

(1)两个线程同时put(),且数组下标意义,那么可能导致前一个线程插入的值被后边的覆盖
(2)扩容导致死循环(头插法),将原本的顺序做了反转,导致死循环

(2)LinkedHashMap

  • 继承自HashMap,维护着一个双重链接列表,此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。

(3)TreeMap

  • 实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序(自然顺序),也可以指定排序的比较器(定制排序),当用Iterator遍历TreeMap时,得到的记录是排过序的

(4)HashTable

  • 继承自Dictionary类
  • 是线程安全的
  • 另外Hashtable不允许key和value为null,并发性不如ConcurrentHashMap。
  • 扩容为原来的2倍+1

(5)Properties

  • 用来处理配置文件,key-value都是string类型
    在这里插入图片描述

4.遍历Collection

(1)使用Iterator

public class CollectionDdemo {
    public static void main(String[] args) {
        Collection collection=new ArrayList();
       collection.add('a');
       collection.add('b');
        Iterator iterator=collection.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

        
    }
}

在这里插入图片描述

(2)使用foreach

public class CollectionDdemo {
    public static void main(String[] args) {
        Collection collection=new ArrayList();
       collection.add('a');
       collection.add('b');
        //增强for循环
        for(Object item:collection){
            System.out.println(item);
        }
    }
}

5.遍历Map

(1)遍历key

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Map1 {
    public static void main(String[] args) {
        Map<String,String> map=new HashMap<>();
        map.put("name","Join");
        map.put("age","18");
        Set set=map.keySet();
        Iterator iterator=set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

在这里插入图片描述

(2)遍历value

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Map2 {
    public static void main(String[] args) {
        Map<String,String> map=new HashMap<>();
        map.put("name","Join");
        map.put("age","18");
        Collection<String> collection=map.values();
        //迭代器
        Iterator iterator=collection.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //foreach
        for (String item:collection
             ) {
            System.out.println(item);
        }
    }
}

在这里插入图片描述

(3)遍历所有键值对

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Map3 {
    public static void main(String[] args) {
        Map<String,String> map=new HashMap<>();
        map.put("name","Join");
        map.put("age","18");

        //迭代器
        Set<String> set1=map.keySet();
        Iterator<String> iterator=set1.iterator();
        while (iterator.hasNext()){
            String key=iterator.next();
            String value=map.get(key);
            System.out.println(key+"->"+value);
        }
        //for循环
        Set set=map.entrySet();
        for(Object obj:set){
            Map.Entry entry=(Map.Entry)obj;
            System.out.println(entry.getKey()+"->"+entry.getValue());
        }
    }
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值