集合(四):java中的各种LIst,Set和Map

  • List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口

  • Set下有HashSet,LinkedHashSet,TreeSet

  • List下有ArrayList,Vector,LinkedList

  • Map下有Hashtable,LinkedHashMap,HashMap,TreeMap

  • Collection接口下还有个Queue接口,有PriorityQueue类
    在这里插入图片描述
    注意:
    Queue接口与List、Set同一级别,都是继承了Collection接口。
    看图你会发现,LinkedList既可以实现Queue接口,也可以实现List接口.只不过呢, LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。

SortedSet是个接口,它里面的(只有TreeSet这一个实现可用)中的元素一定是有序的。

LIST

在Collection中,List集合是有序的,Developer可对其中每个元素的插入位置进行精确地控制,可以通过索引来访问元素,遍历元素。

在List集合中,我们常用到ArrayList和LinkedList这两个类。
ArrayList
ArraylIst初始容量为0,当他添加了一个元素后,初始容量变为10
集合扩容:在0<newCapacity<MAX_ARRAY_SIZE的范围内,每次增加原来的0.5倍;

newCapacity=1.5 * oldCapacity;
参考:https://blog.csdn.net/m0_37550986/article/details/90652901?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

其中,ArrayList底层通过数组实现,随着元素的增加而动态扩容。而LinkedList底层通过链表来实现,随着元素的增加不断向链表的后端增加节点。
ArrayList是Java集合框架中使用最多的一个类,是一个数组队列,线程不安全集合。
它继承于AbstractList,实现了List, RandomAccess, Cloneable, Serializable接口。

(1)ArrayList实现List,得到了List集合框架基础功能;
(2)ArrayList实现RandomAccess,获得了快速随机访问存储元素的功能,RandomAccess
是一个标记接口,没有任何方法;
(3)ArrayList实现Cloneable,得到了clone()方法,可以实现克隆功能;
(4)ArrayList实现Serializable,表示可以被序列化,通过序列化去传输,典型的应用
就是hessian协议。

它具有如下特点:

1.容量不固定,随着容量的增加而动态扩容
2.有序集合(插入的顺序==输出的顺序)
3.插入的元素可以为NULL
4.查的效率更高
5.线程不安全

ArrayList和List之间相互转换的几种方法:
一、ArrayList–>List
1.通过 Arrays.asList(strArray) 方式,将数组转换List后,不能对List增删,只能查改,否则抛异常。
程序在list.add(“1”)处,抛出异常:UnsupportedOperationException。

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at com.darwin.junit.Calculator.testArrayCastToList(Calculator.java:19)
	at com.darwin.junit.Calculator.main(Calculator.java:44)

原因解析:
Arrays.asList(strArray)返回值是java.util.Arrays类中一个私有静态内部类java.util.Arrays.ArrayList,它并非java.util.ArrayList类。java.util.Arrays.ArrayList类具有 set(),get(),contains()等方法,但是不具有添加add()或删除remove()方法,所以调用add()方法会报错。
使用场景:Arrays.asList(strArray)方式仅能用在将数组转换为List后,不需要增删其中的值,仅作为数据源读取使用。

2.数组转为List后,支持增删改查的方式
通过ArrayList的构造器,将Arrays.asList(strArray)的返回值由java.util.Arrays.ArrayList转为java.util.ArrayList。

关键代码:ArrayList list = new ArrayList(Arrays.asList(strArray)) ;

public static void main(String[] args) {
        String[] strArray = new String[2];
        ArrayList<String> list = new ArrayList<>(Arrays.asList(strArray)) ;
        list.add("1");
        System.out.println(list);
    }

执行结果:成功追加一个元素“1”。

[null, null, 1]

3.通过集合工具类Collections.addAll()方法(最高效)
通过Collections.addAll(arrayList, strArray)方式转换,根据数组的长度创建一个长度相同的List,然后通过Collections.addAll()方法,将数组中的元素转为二进制,然后添加到List中,这是最高效的方法。

关键代码:

ArrayList< String> list = new ArrayList<String>(strArray.length);
Collections.addAll(list, strArray);
public class ArrayTrsfList {
    public static void main(String[] args) {
        String[] strArray = new String[2];
        ArrayList< String> list = new ArrayList<String>(strArray.length);
        Collections.addAll(list, strArray);
        list.add("1");
        System.out.println(list);
    }
}

二、List–>ArrayList
1.` 使用for循环

public static void main(String[] args) {
        List<String> list=new ArrayList<String>();
        list.add("hello");
        list.add("world");       
        String[] str1=new String[list.size()];
        for(int i=0;i<list.size();i++) {
            str1[i]=list.get(i);
        }
        for (String string : str1) {
            System.out.println(string);
        }
    }

2.使用List中的toArray()方法

 public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        String[] strings = list.toArray(new String[list.size()]);
        for (String str : strings) {
            System.out.println(str);
        }
    }

LinkedList

LinkedList是一个双向链表,每一个节点都拥有指向前后节点的引用。相比于ArrayList来说,LinkedList的随机访问效率更低。
它继承AbstractSequentialList,实现了List, Deque, Cloneable, Serializable接口。

(1)LinkedList实现List,得到了List集合框架基础功能;
(2)LinkedList实现Deque,Deque 是一个双向队列,也就是既可以先入先出,
又可以先入后出,说简单些就是既可以在头部添加元素,也可以在尾部添加元素,增删的效率更高;
(3)LinkedList实现Cloneable,得到了clone()方法,可以实现克隆功能;
(4)LinkedList实现Serializable,表示可以被序列化,通过序列化去传输,典型的应用
就是hessian协议。

Vector
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程安全,效率低
在这里插入图片描述
在这里插入图片描述

—Set 无序,唯一

HashSet
底层数据结构是哈希表。(无序,唯一)
如何来保证元素唯一性?
1.依赖两个方法:hashCode()和equals()

LinkedHashSet
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
1.由链表保证元素有序
2.由哈希表保证元素唯一

TreeSet
底层数据结构是红黑树。(唯一,有序)

  • 如何保证元素排序的呢?
    自然排序
    比较器排序
    2.如何保证元素唯一性的呢?
    根据比较的返回值是否是0来决定

TreeSet, LinkedHashSet and HashSet 的区别
1.介绍

1.TreeSet的主要功能用于排序
2.LinkedHashSet的主要功能用于保证FIFO即有序的集合(先进先出)
3.HashSet只是通用的存储数据的集合

2.相同点

1.因为三者都实现Set interface,所以三者都不包含duplicate elements
2.三者都不是线程安全的,如果要使用线程安全可以Collections.synchronizedSet()

3.不同点

  • HashSet插入数据最快,其次LinkHashSet,最慢的是TreeSet因为内部实现排
  • HashSet不保证有序,LinkHashSet保证FIFO即按插入顺序排序,TreeSet安装内部实现排序,也可以自定义排序规则
  • HashSet和LinkHashSet允许存在null数据,但是TreeSet中插入null数据时会报NullPointerException

Map

在这里插入图片描述
Map接口有三个比较重要的实现类,分别是HashMap、TreeMap和HashTable。

TreeMap是有序的,HashMap和HashTable是无序的。
Hashtable的方法是同步的,HashMap的方法不是同步的。这是两者最主要的区别。

这就意味着:


 - Hashtable是线程安全的,HashMap不是线程安全的。
 - HashMap效率较高,Hashtable效率较低。
 - 如果对同步性或与遗留代码的兼容性没有任何要求,建议使用HashMap。 查看Hashtable的
源代码就可以发现,除构造函数外,Hashtable的所有 public 方法声明中都有 synchronized
关键字,而HashMap的源码中则没有.
 - Hashtable不允许null值,HashMap允许null值(key和value都允许)
 - 父类不同:Hashtable的父类是Dictionary,HashMap的父类是AbstractMap

参考:

  • https://blog.csdn.net/zhangqunshuai/article/details/80660974?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159896493119195264547442%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=159896493119195264547442&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-4-80660974.pc_ecpm_v3_pc_rank_v3&utm_term=java%E4%B8%AD%E7%9A%84list&spm=1018.2118.3001.4187
  • https://blog.csdn.net/weixin_43314519/article/details/106171916?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159895998119724836757595%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159895998119724836757595&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v3~pc_rank_v3-1-106171916.pc_ecpm_v3_pc_rank_v3&utm_term=listarraylistlinkedlist+java&spm=1018.2118.3001.4187
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值