集合

Collection接口

在这里插入图片描述Collection接口中常用方法:

add(Object obj)addAll(Collection coll)size()
isEmpty()clear()contains(Object obj)
containsAll(Collection coll)remove(Object obj)removeAll(Collection coll)
equals(Object obj)hasCode()toArray()
retainsAll(Collection coll)iterator()

Collection集合与数组之间的转换:

//集合 --->数组:toArray()
Collection coll = new ArrayList();
Object[] arr = coll.toArray();
//数组 --->集合:调用Arrays类的静态方法asList()
List<String> list = Arrays.asList(new String[]{"AA", "BB", "CC"});
List arr2 = Arrays.asList(new Integer[]{123, 456});

注意点:向Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals()

遍历Collection的两种方式

  1. 使用迭代器Iterator
  2. 增强 for
Collection coll = new ArrayList();
Iterator iterator = coll.iterator();
//hasNext():判断是否还有下一个元素
while(iterator.hasNext()){
    //next():①指针下移 ②将下移以后集合位置上的元素返回
    System.out.println(iterator.next());
}

//for(集合元素的类型 局部变量 : 集合对象)
//内部仍然调用了迭代器。
for(Object obj : coll){
    System.out.println(obj);
}

List接口

常用方法:

add(Object obj)增加
remove(int index) / remove(Object obj)删除
set(int index,Object obj)修改
get(int index)查询
add(int index,Object obj)插入
size()长度

常用实现类:

  1. ArrayList:作为List接口的主要实现类;存储有序的、可重复的数据;线程不安全的,效率高;底层使用Object[] elementData存储
  2. LinkedList:对于频繁的插入、删除操作,使用此类效率比ArrayList高;存储有序的、可重复的数据;底层使用双向链表存储
  3. Vector:作为List接口的古老实现类;存储有序的、可重复的数据;线程安全的,效率低;底层使用Object[] elementData存储

源码分析:

  1. ArrayList(JDK 7中)
    ArrayList list = new ArrayList(),底层创建了长度是10的Object[]数组elementData
    list.add(11),如果此次的添加导致底层elementData数组容量不够,则扩容。 默认情况下,扩容为原来的容量的1.5倍,同时需要将原有数组中的数据复制到新的数组中。

  2. ArrayList(JDK 8中)
    ArrayList list = new ArrayList(),底层Object[] elementData初始化为{},并没有创建长度为10的数组
    list.add(123),第一次调用add()时,底层才创建了长度10的数组,并将数据123添加到elementData[0],后续的添加和扩容操作与jdk 7 无异。

  3. LinkedList(双链表)
    LinkedList list = new LinkedList(),内部声明了Node类型的first和last属性,默认值为null
    list.add(123),将123封装到Node中,创建了Node对象

  4. Vector
    jdk7jdk8中通过Vector()构造器创建对象时,底层都创建了长度为10的数组。在扩容方面,默认扩容为原来的数组长度的2倍。

Set接口

存储数据的特点:无序的,不可重复的数据

  1. 无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的。

  2. 不可重复性:保证添加的元素按照equals()判断时,不能返回true,即相同的元素只能添加一个。

添加元素的过程

  1. HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(索引位置),判断数组此位置上是否已经有元素
  2. 如果此位置上没有其他元素,则元素a添加成功。
  3. 如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值,如果hash值不相同,则元素a添加成功
  4. 如果hash值相同,进而需要调用元素a所在类的equals()方法,equals()返回true,元素a添加失败,equals()返回false,则元素a添加成功

常用实现类

  1. HashSet:作为Set接口的主要实现类;存储无序的、不可重复的数据;线程不安全的;可以存储null
  2. LinkedHashSet:作为HashSet的子类;存储无序的、不可重复的数据;遍历其内部数据时,可以按照添加的顺序遍历;对于频繁的遍历操作,LinkedHashSet效率高于HashSet.
  3. TreeSet:存储无序的、不可重复的数据;可以按照添加对象的指定属性,进行排序。

注意点

  1. Set(HashSet、LinkedHashSet)中添加的数据,其所在的类一定要重写hashCode()equals();重写的hashCode()equals()尽可能保持一致性:相等的对象必须具有相等的散列码
  2. 自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals();定制排序中,比较两个对象是否相同的标准为:compare()返回0,不再是equals()

Map接口

常用实现类:

  1. HashMap:作为Map的主要实现类;双列数据,存储键值对的数据;线程不安全的,效率高;可以存储nullkeyvalue
  2. LinkedHashMap:双列数据,存储键值对的数据;保证在遍历map元素时,可以按照添加的顺序实现遍历,由于HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素;对于频繁的遍历操作,此类执行效率高于HashMap
  3. TreeMap:双列数据,存储键值对的数据;保证按照添加的键值对进行排序,实现排序遍历,此时考虑key的自然排序或定制排序;底层使用红黑树
  4. Hashtable:双列数据,存储键值对的数据;作为古老的实现类;线程安全的,效率低;不能存储nullkeyvalue
  5. Properties:常用来处理配置文件。keyvalue都是String类型

存储结构的理解

  1. Map中的key:无序的、不可重复的,使用Set存储所有的key
  2. Map中的value:无序的、可重复的,使用Collection存储所有的value
  3. Map中的entry:无序的、不可重复的,使用Set存储所有的entry
    在这里插入图片描述

常用方法:

put(Object key,Object value)添加
remove(Obejct key)删除
put(Object key,Object value)修改
get(Object key)查询
size()长度
keySet() / values() / entrySet()遍历

JDK 7内存结构说明:

  1. HashMap map = new HashMap(),实例化后,底层创建了长度是16的一维数组Entry[] tablemap.put(key1,value1),首先调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。如果此位置上的数据为空,此时的key1-value1添加成功。
  2. 如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(以链表形式存在)),比较key1和已经存在的一个或多个数据的哈希值,如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功
  3. 如果key1的哈希值和已经存在的某一个数据(key2-value2)的哈希值相同,调用key1所在类的equals(key2)方法继续比较,如果equals()返回false,此时key1-value1添加成功;如果equals()返回true,使用value1替换value2
  4. 在不断的添加过程中,会涉及到扩容问题,当超出临界值(且要存放的位置非空)时,扩容。默认的扩容方式是扩容为原来容量的2倍,并将原有的数据复制过来。

JDK 8相较于JDK 7底层实现的不同

  1. new HashMap():底层没有创建一个长度为16的数组
  2. jdk 8底层的数组是:Node[],而非Entry[]
  3. 首次调用put()方法时,底层才创建长度为16的数组
  4. jdk 7底层结构只有:数组+链表。jdk 8中底层结构:数组+链表+红黑树。
  5. 形成链表时,jdk 7中新的元素指向旧的元素;jdk 8中旧的元素指向新的元素
  6. 当数组的某一个索引位置上的元素以链表形式存在的数据个数 > 8 且当前数组的长度 > 64时,此时此索引位置上的所数据改为使用红黑树存储。

HashMap底层典型属性的说明

属性名说明默认值
DEFAULT_INITIAL_CAPACITYHashMap的默认容量16
DEFAULT_LOAD_FACTORHashMap的默认加载因子0.75
threshold扩容的临界值容量*填充因子:16 * 0.75 => 12
TREEIFY_THRESHOLDBucket中链表长度大于该默认值转化为红黑树
MIN_TREEIFY_CAPACITY桶中的Node被树化时最小的hash表容量64

Conlections工具类

常用方法:

reverse(List)反转 List 中的元素的顺序
shuffle(List)对 List 集合元素进行随机排序
sort(List)根据元素的自然顺序对指定 List 集合元素升序排序
sort(List,Comparator)根据指定的Comparator产生的顺序对 List 集合元素进行排序
swap(List,int,int)将指定 List 集合中的 i 处元素和 j 处元素进行交换
Object max(Collection)根据元素的自然顺序,返回给定集合中的最大元素
Object max(Collection,Comparator)根据 Comparator 指定顺序,返回给定集合中最大的元素
Object min(Collection)根据元素的自然顺序,返回给定集合中的最小元素
Object min(Collection,Comparator)根据 Comparator 指定顺序,返回给定集合中最小的元素
int frequency(Collection,Object)返回指定集合中指点元素的出现次数
void copy(List,dest,sre)将src的内容复制到dest中
boolean replaceAll(List list,Object oldVal,Object newVal)使用新值替换 List 对象的所有旧值

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值