java 集合Collection

更好的阅读体验
一. 集合框架的概述

  1. 数组,集合都是对多个数据进行存储操作的结构,简称Java容器。
    a. 说明:存储是内存层面的存储,不是持久化的存储
    b. 数组一旦定义,长度和类型就固定。

  1. 集合框架
    a. Collection接口:单列集合,用来存储一个一个的对象
    ⅰ. List接口:存储有序的,可重复的数据—>"动态"数组

    1. ArrayList : 作为List接口的主要实现类;线程不安全,效率高;底层用Object[]存储
      a. 开始创建长度为10的Object[] ,不够后扩容,默认是原来的容量的1.5倍
      b. 且原有数据赋值给新的数组
      c. 结论:建议开发中使用带参的构造器
      d. jdk8 中的新变化:底层Object[] elementData={}没有创建数组,add()后才创建长度为10的数组
      e. 相当于单例模式中的懒汉式,节省空间
    2. LinkedList:对频繁的删除、插入操作,使用此类必ArrayList效率高;底层使用双向链表存储
    3. Vector:作为List接口的古老实现类;线程安全,效率低;底层用Object[]存储

    ⅱ. Set接口:存储无序的,不可重复的数据

    1. HashSet:作为 Set接口的主要实现类;线程不安全,可以存储null值
      a. 无序性:不等于随机性,存储的数据在底层数组中并非按照数组的索引进行的顺序添加,而是根据数据的哈希值
      b. 不可重复性:保证添加的元素按照equals()判断时,不能返回true。即相同元素只能添加一个
      c. 添加元素的过程,以HashSet为例
      d. 我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置,判断
      数组此位置上是否已经元素:
      如果此位置上没其他元素,则元素a添加成功。 —>情况1
      如果此位置上其他元素b(或以链表形式存在的多个元素,则比较元素a与元素b的hash值:
      如果hash值不相同,则元素a添加成功。—>情况2
      如果hash值相同,进而需要调用元素a所在类的equals()方法:
      equals()返回true,元素a添加失败
      equals()返回false,则元素a添加成功。—>情况3
      对于添加成功的情况2和情况3而言:元素a 与已经存在指定索引位置上数据以链表的方式存储。
      jdk 7 :元素a放到数组中,指向原来的元素。
      jdk 8 :原来的元素在数组中,指向元素a
      总结:七上八下
      e.
      f. Set接口没有新增的方法
      g. 要求1:向Set中添加的数据,其所在类一定要重写hashCode()和equals()
      h. 要求2:重写的equals()和hashCode()尽可能保持一致性.相同的对象有相同的哈希值/散列码
    2. LinkedHashSet:作为HashSet的子类,遍历时,可以按添加的顺序遍历
      a. 作为HashSet的子类,在添加数据的同时,每个数据还维护两个引用,记录前后的数据
      b. 对于频繁的遍历遍历操作,LinkedHashSet比HashSet效率高
    3. TreeSet:可以按照添加对象的指定属性进行排序
      a. 向TreeSet中添加的数据,要求是相同类的对象
      b. 两种排序方式:自然排序(实现Comparable接口)和定制排序
      c. 自然排序中,比较两个对象是否相同的标准为:compareTo返回0,不再是equals()
      d. 定制排序中,比较两个对象是否相同的标准为:compare返回0,不再是equals()
      e.
      b. Map接口:双列集合,用来存储一对一对的数据
      ⅰ. HashMap, linkedHashMap, TreeMap, Hashtable, Properties

  1. 集合方法
    a. 向接口实现类的对象添加数据obj时,要求重写equals()
    b. add(), addAll(), clear(), remove(), removeAll(), retainAll()求并集,保留共有的
    c. isEmpty()判空, contains()是否包含元素, containsAll()是否包含集合
    d. toArray() 集合—>数组,Arrays.asList() 数组—>集合
    e. hashCode() 返回对象的哈希值,size()返回元素多少,iterator() 得到迭代器
    f. equals() 要想返回true,需要当前集合和形参集合的元素都相同

  1. Iterator迭代器接口
    a. 内部方法:hasNext(), next()
    b.
    while(iterator.hasNext())
    {
    System.out.println(iterator.next());
    }
    c. remove(): 删除元素 注意 Arrays.asList返回的List不可修改
    d. while(iterator.hasNext())
    {
    Object obj = iterator.next();
    if (new Integer(123).equals(obj))
    {
    iterator.remove();
    }
    }

  1. 新特性foreach
    a. for(集合元素的类型 局部变量:集合对象)
    b. for (Object obj: coll) // 是值传递,不能修改原数据
    {
    System.out.println(obj);
    }
    c. 内部仍然用迭代器

  1. List常用方法
    a. void add(int index, Object ele) 在index位置插入ele元素
    b. boolean addAll(int index, Collection eles) 在index位置插入整个集合元素
    c. Object remove(int index) 删除index位置中的元素,并返回
    d. Object set(int index, Object ele) 修改index位置上的元素为ele
    e. Object get(int index) 查询获得index位置上的元素
    f. int indexOf(Object obj) 查询返回obj在当前集合中首次出现的位置,无则返回-1
    g. int lastIndexOf(Object obj) 查询返回obj在当前集合中末次出现的位置,无则返回-1
    h. List subList(int fromIndex, int toIndex) 查询返回从fromIndex到toIndex元素组成的左闭右开子集合
    i. 总结
    ⅰ. 增:add(Object obj)
    ⅱ. 删: remove(Object obj) / remove(int index)
    ⅲ. 改: set(int index, Object obj)
    ⅳ. 查: get(int index) / indexOf(Object obj) / lastIndexOf(Object obj)
    ⅴ. 插: add(int index, Object obj) / add(int index, Collection coll)
    ⅵ. 大小: size() (ps: 数组用长度length, 集合用大小size)
    ⅶ. 遍历:
    1. iterator迭代器遍历
      a. Iterator it = list.iterator();
      while(it.hasNext())
      {
      System.out.println(it.next());
      }
    2. 增强for循环
      a. for (Object obj: list)
      {
      System.out.println(obj);
      }
    3. 普通for循环
      a. for (int i = 0; i < list.size(); i++) {
      System.out.println(list.get(i));
      }

  1. Map接口
    a. 在这里插入图片描述

    b. HashMap : 作为Map的主要实现类;线程不安全,效率高;可以存储null的key和value
    i. LinkedHashMap:遍历Map元素时,可以按照添加的顺序遍历

    1. 原因:在原有的HashMap基础上,加了一对指针,指向前后俩个元素
    2. 频繁的遍历操作,其效率会更高

    ⅱ. HashMap底层

    1. 数组+链表 (jdk7及之前)
    2. 数组+链表+红黑树 (jdk8)

    c. TreeMap:保证按照添加key-value进行排序-考虑key的自然或定制排序-实现排序遍历
    ⅰ. 底层使用红黑树
    d. Hashtable:作为Map的古老实现类;线程安全,效率低;不可以存储null的key和value
    ⅰ. Properties:常用来处理配置文件,key和value都是String类型
    e. Map结构的理解
    ⅰ. Map中的key:无序的、不可重复的,使用Set存储所的key —> key所在的类要重写equals()和hashCode() (以HashMap为例)
    ⅱ. Map中的value:无序的、可重复的,使用Collection存储所的value —>value所在的类要重写equals()
    ⅲ. 一个键值对:key-value构成了一个Entry对象。
    ⅳ. Map中的entry:无序的、不可重复的,使用Set存储所的entry
    f. HashMap底层实现原理-以jdk7为例
    ⅰ. HashMap map = new HashMap();
    ⅱ. 在实例化以后,底层创建了长度是16的一维数组Entry[] table.
    ⅲ. …可能已经执行过多次put…
    ⅳ. map.put(key1, value1):
    ⅴ. 首先,调用key1所在类的hashCode()计算key1的哈希值,此哈希值再经过某种算法计算后,得到这对再Entry数组中的存放位置

    1. 如果此位置上数据为空,此时的这对key1-value1添加成功。—情况1
    2. 如果此位置上数据不为空,(可能存在一个或多个数据(链式)),比较key1与这个位置上的数据的哈希值
      a. 如果key1的哈希值与它们都不相同,此时这对key1-value1添加成功。—情况2
      b. 如果key1与其中一个数据(key2-value2)哈希值相同,则继续比较:调用key1所在类的equals(key2)
      ⅰ. 如果equals() 返回false:此时这对key1-value1添加成功—情况3
      ⅱ. 如果equals() 返回true:使用value1替换value2
      ⅵ. 补充:关于情况2和情况3此时的key1-value1和原来的数据以链表的方式存储
      ⅶ. 在不断的添加过程中,当超出临界值且存放位置非空,会涉及扩容问题,默认的扩容方式:扩容为原来的2倍,并将原有的数据复制过来

    g. jdk8 相较于jdk7在底层实现方面的不同
    ⅰ. new HashMap(): 底层没有创建一个长度为16的数组
    ⅱ. jdk 8底层的数组是:Node[], 而非Entry[]
    ⅲ. 首次调用put方式时,底层创建长度16的数组
    ⅳ. jdk7 底层结构只有: 数组+链表。jdk8 中底层结构:数组+链+红黑树

    1. 当数组的某一个索引位置上的元素以链表形式存在的数据个数 > 8 且当前数组的长度 > 64时,
    2. 此时此索引位置上的所有数据改为使用红黑树存储。

    h. HashMap源码中的重要常量

    i. Map中定义的方法
    a. 添加:put(Object key,Object value), putAll(Map m):
    b. 删除:remove(Object key), clear()
    c. 修改:put(Object key,Object value)
    d. 查询:get(Object key),containsKey(Object key),containsValue(Object value),isEmpty(),equals()
    e. 长度:size()
    f. 遍历:KeySet(); values(); entrySet();
    ⅰ. Set set = map.keySet();
    Iterator iterator = set.iterator();
    while (iterator.hasNext())
    {
    Object key = iterator.next();
    Object value = map.get(key);
    System.out.println(key + “—>” + value);
    }
    for (Object key : set)
    {
    Object value = map.get(key);
    System.out.println(key + “—>” + value);
    }
    ⅱ. Collection values = map.values();
    for (Object o : values )
    {
    System.out.println(o);
    }
    ⅲ. Set set1 = map.entrySet();
    for (Object o : set1)
    {
    Map.Entry entry = (Map.Entry) o;
    System.out.println(entry.getKey()+ “---->” +entry.getValue());
    }

    j. TreeMap的两种添加方式
    ⅰ. 向TreeMap中添加key-value,要求key必须是同一个类创建的对象
    ⅱ. 因为要按照key进行排序:自然排序(对key的类comparable),定制排序(new comparator())
    k. Properties 处理配置文件
    l. Collections: 操作Collection,Map的工具类
    ⅰ. 常用方法

    1. reverse(List):反转 List 中元素的顺序
    2. shuffle(List):对 List 集合元素进行随机排序
    3. sort(List):根据元素的自然顺序对指定 List 集合元素升序排序
    4. sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
    5. swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
    6. Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
    7. Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
    8. Object min(Collection)
    9. Object min(Collection,Comparator)
    10. void copy(List dest,List src):将src中的内容复制到dest中
    11. boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所旧值
    12. synchronizedList(List list) 和 synchronizedMap(Map map)ArrayList和HashMap都是线程不安全的,如果程序要求线程安全,我们可以将ArrayList、HashMap转换为线程的

    m. Arrays工具类常用方法

    1. boolean equals(int[] a,int[] b):判断两个数组是否相等。
    2. String toString(int[] a):输出数组信息。将数组转换为字符串
    3. void fill(int[] a,int val):将指定值填充到数组之中。
    4. void sort(int[] a):对数组进行排序。
    5. int binarySearch(int[] a,int key):利用二分法查找元素
    6. public static List asList(T… a):将数组转换为List
    7. public static int[] copyOf(int[] original, int newLength):复制数组original, 从0索引开始,长度为newLength,返回 一个新数组
    8. public static int[] copyOfRange(int[] original, int from, int to):复制数组 original, 从from 开始,到to 结束,左闭右开
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值