list接口的实现对象

  • 有序(存入和取出的顺序一致),元素都有索引(角标),元素可以重复。

ArrayList:

内部是数组数据结构(有序),但是不同步的,替代了Vector,如果想要保证线程安全,则可以手动在数据修改处加锁。特点——查询的速度很快

扩容机制:
如果内部数组满了,那么数组列表就会自动创建一个更大的新数组,然后将所有对象拷贝过去

  • 容器类对象在调用 remove、 contains等方法时需要比较对象是否相等时,会涉及到对象类型的equals方法和 hashCode方法(Map类型,如果是List接口,仅需判断equals)
  • 对于自定义的类型,需要要重写 equals和 hashCode方法以实现自定义的对象相等规则。
  • 注意:相等的对象应该具有相等的 hash codes。



    LinkedList:

    内部是链表数据结构,是不同步的。特点——增删元素的速度很快


set接口的实现对象

  • 存储的数据特点:无序的(根据数组的hash值存储的,而不是索引)、存储元素是不可重复的
  • Set判断两个对象是否相同不是使用==运算符,而是根据 equals()方法

HashSet


  1. hashSet的底层就是HashMap
  2. HashSet是线程不安全的。
  3. HashSet通过对象的hashCode和equals方法来完成对象唯一性的。
  4. 扩容机制:当数组的使用率超过0.75时,扩容容量2倍

判断条件是这样的:

  • 如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
  • 如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
  • 如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。

记住:如果将一个数据存储到HashSet集合中,必须覆盖hashCode方法和equals方法。
List、Set、Map - 图1

LinkHashSet

  • 作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历,但是并不是代表LinkedHashSet是有序的
  • 其内部还维护了两个引用(链表),因此添加删除数据会更快

TreeSet

  1. 底层用红黑树存储,所以TreeSet判断对象是否相同是用ComparaTo的返回值来确定的,如果返回0,则认为两个比较对象是相同的
  2. 向TreeSet中添加的数据,要求是相同类的对象。
  3. 可以对Set集合中的元素进行排序。是线程不安全的。

TreeSet的两种排序

TreeSet对元素进行排序的方式一(自然排序):

  • 让元素自身具备比较功能:需要实现Comparable接口,覆盖compareTo方法。

TreeSet集合第二种排序方式(定制排序):

  • 让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。
  • 将该类对象作为参数传递给TreeSet集合的构造函数。

    1. public void test2(){
    2. Comparator com = new Comparator() {
    3. //照年龄从小到大排列
    4. @Override
    5. public int compare(Object o1, Object o2) {
    6. if(o1 instanceof User && o2 instanceof User){
    7. User u1 = (User)o1;
    8. User u2 = (User)o2;
    9. return Integer.compare(u1.getAge(),u2.getAge());
    10. }else{
    11. throw new RuntimeException("输入的数据类型不匹配");
    12. }
    13. }
    14. };
    15. TreeSet set = new TreeSet(com);//有参数就按照定制排序
    16. }

Map接口的实现对象

  • Map(K,V):Map一次添加一对元素(键值对),key-value构成了一个entry对象。
  • map集合中必须保证键的唯一性
  • Key所在的类需要重新equals方法和hashCode方法

image.png

底层实现:

  • 扩容向题:护容为原来容量2倍,并将原有的数据复制过来。
  • jdk8时,首次put才创建数组(长度为16),类似懒汉式,而jdk7是饿汉式
  • 在jdk7时HashMap是数组+链表的结构,HashMap是数组+链表+红黑树
  • 当数组的某一个索引位置上的元素以链表形式存在的数据个数 > 8 且当前数组的长度 > 64时,此时此索引位置上的所数据改为使用红黑树存储。

Hashtable

  • 开发中已经不怎么用了
  • Hashtable :内部结构是哈希表,线程安全的。
  • 不允许null作为键、null作为值。

有个子类 Properties: 常用来处理配置文件。key和value都是String类型

HashMap:

  • 线程不安全的,效率快;
  • 可以存储null的key和value

有个子类LinkedHashMap:效率更快

TreeMap:

  • 保证照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序或定制排序
  • 底层使用红黑树
  • 是线程不安全的

迭代Map

由于Map没有直接实现Iterator方法所以无法直接遍历Map。
但是有三个方法可以间接进行迭代取出Map集合中元素。


方法一:keySet()
我们可以通过keySet()方法获取map中所有的键组成的Set集合,再通过Set集合的迭代器方法取到键,最后根据键去取值就可以了。

List、Set、Map - 图3


方法二:entrySet()
该方法将键值对映射关系作为对象存储到了Set集合中,而这个映射关系的类型就是Map.Entry( )类型。(是一个整体)

Map中的entry:无序的、不可重复的,使用Set存储所的entry

List、Set、Map - 图4

  • Map.Entry有getKey( )和getValue( )供调用。




    方法三:values()
    利用多态,向上抽取父类,调用父类collection的values方法
    List、Set、Map - 图5

Collections工具类

操作List、Set和Map集合的工具类

  • Collections中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作
  • 还提供了对集合对象设置不可变、对集合对象实现同步控制等方法