Java集合
Java集合是Java开发过程中重要的存储单位(个人理解),简单理解掌握Java的集合分类及底层实现原理对开发有很大的帮助,属于基础中的基础。
数组和集合的区别
(1)数组的长度固定,集合的长度可变
(2)数组既可以存储基本数据类型数据,也可以存储引用数据类型
集合只能存储引用数据类型
Conllection接口
Conllection接口是Set集合和List集合的顶级父类接口,也是所有单列集合的顶级父类。内置多个操作集合的方法,其子类都可继承、
collection主要方法
boolean add(Object o):添加对象到集合
boolean remove(Object o):删除指定的对象
int size():返回当前集合中元素的数量
boolean contains(Object o):查找集合中是否有指定的对象
boolean isEmpty():判断集合是否为空
Iterator iterator():返回一个迭代器
boolean containsAll(Collection c):查找集合中是否有集合c中的元素
boolean addAll(Collection c):将集合c中所有的元素添加给该集合
void clear():删除集合中所有元素
void removeAll(Collection c):从集合中删除c集合中也有的元素
void retainAll(Collection c):从集合中删除集合c中不包含的元素
List集合
list集合接口继承Conllection顶级父类。其下主要有两个常用实现类ArrayList 和 linkedList
特点:有序的、可重复的、按索引位置排序 (这点类似于数组)
ArrayList
ArrayList 底层是数组实现 可保持插入顺序,元素可重复。
特点:
1.ArrayList长度可变的数组,所以每个元素都有索引,所以其查询较快。
2.允许对元素进行快速的随机访问(根据索引进行访问)
3.向ArrayList中插入和删除元素的速度较慢,增删比较慢的原因ArrayList底层是数组结构,然后数组结构的长度是不可改变的,所以ArrayList增加删除元素的时候都是创建一个新的数组.
遍历:朴实for循环即可
LinkedList
linkedList底层是双向链表结构可保持顺序插入,
特点:
1.插入、删除元素较快,但随即访问较慢(链表特性)
遍历:它的查找是分两半查找,先判断index是在链表的哪一半,然后再去对应区域查找,这样最多只要遍历链表的一半节点即可找到
https://blog.csdn.net/The_Best_Hacker/article/details/81368079
Set集合
同样是继承conllection接口,其下主要有两个常用实现类:HashSet和LindkedHashSet
特点:其元素不可重复,切存储和取出元素是无序的。
HashSet
HashSet按照Hash算法存储集合中的元素,(底层是哈希表)具有很好的存取和查找性能
HashSet保证数据唯一性的原理:
使用add方法添加的时候,add方法的底层依赖了hashCode()和equals()方法.
当通过add添加元素的时候,会先通过hashCode()方法计算该元素的哈希值 将哈希值和集合中的其他元素的哈希值进行比较, 如果没有哈希值相同的,直接添加,此时不会调用equals()方法。
如果有相同的,此时会调用equals()方法来比较 其中的内容,如果为true,说明是同一个元素,则不添加,如果为false,说明不是同一个元素,则添加。
这里其实是两层过滤,hashCode()是第一层过滤(粗过滤),equals()是第二次过滤(完全过滤)
此时如果我们尽量让hashCode()确定元素是否相同,这样就可以减少equals()方法调用,就可以提高效率
如果我们要保证元素的唯一性就应该重写hashCode()和equals()方法
特点:
1.存储顺序和添加的顺序不同
2.HashSet不是同步的,如果多个线程同时访问一个HashSet,假设有两个或更多的线程修改了集合中的值,则必须通过代码使线程同步。
3.HastSet允许集合中的元素为null。
linkedHashSet
LinkedHashMap继承于HashMap,底层使用哈希表和双向链表来保存所有元素,比父类多了一个双向链表,可以保证有序 它的功能(方法)和特点基本上与父类一致,只有一点,它可以保证有序并且它是非同步,允许使用null值和null键。
Map集合接口
Map集合
Map接口是双列集合的顶层接口,它和Collection接口没有继承关系,双列集合和单列集合是独立的两个体系, 它们的功能(方法)不太一样
Map集合的体系和Set集合的体系非常相似,因为Set集合底层就使用了Map集合,比如HashSet底层调用了HashMap
Map接口的特点
(1)双列集合,存储的值有两列,第一列叫键(Key),第二列叫值(Value)
(2)键和值是一一对应的,键只能对应唯一的值
(3)键不能重复,值可以重复
如果键重复,只会保留一个不会报错,值进行覆盖
HashMap
存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需
要重写键的hashCode()方法、equals()方法。
HashMap的主干是一个Entry数组。Entry是HashMap的基本组成单元,每一个Entry包含一个key-value键值对。
HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表(当前entry的next指向null),那么对于查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度为O(n),首先遍历链表,存在即覆盖,否则新增;对于查找操作来讲,仍需遍历链表,然后通过key对象的equals方法逐一比对查找。所以,性能考虑,HashMap中的链表出现越少,性能才会越好。
原文:https://blog.csdn.net/qq_40118851/article/details/82804510
LinkedHashMap
HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。 通过链
表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的
hashCode()方法、equals()方法。
HashMap和Hashtable的区别
(1)HashMap线程不安全,线程不同步,没有加同步锁,效率高
Hashtable线程安全,线程同步,加了同步锁,效率低
(2)HashMap可以存储null键和null值,可以将null作为键或者值
Hashtable不可以存储null键和null值,不可以将null作为键或者值,否则会报空指针异常(NullPointerException)
Map集合的四种遍历方式
Java 9,添加了几种集合工厂方法,更方便创建少量元素的集合、map实例。新的List、Set、Map的静态工厂方法可
以更方便地创建集合的不可变实例。
public class HelloJDK9 {
public static void main(String[] args) {
Set str1=Set.of(“a”,“b”,“c”);
//str1.add(“c”);这里编译的时候不会错,但是执行的时候会报错,因为是不可变的集合
System.out.println(str1);
Map<String,Integer> str2=Map.of(“a”,1,“b”,2);
System.out.println(str2);
List str3=List.of(“a”,“b”);
System.out.println(str3);
}
}