美文网首页Java工程师知识树
Java基础-集合类-概述

Java基础-集合类-概述

作者: HughJin | 来源:发表于2020-12-29 06:56 被阅读0次

    Java工程师知识树 / Java基础


    1.为什么要用集合类

    Java编程思想中指出:

    通常,程序总是根据运行时才知道的某些条件去创建新对象。
    在此之前,不会知道所需对象的数量,甚至不知道确切的类型。
    为解决这个普遍的编程问题,需要在任意时刻和任意位置创建任意数量的对象。
    所以,就不能依靠创建命名的引用来持有每一个对象:
    MyType aReference;
    因为你不知道实际上会需要多少这样的引用。
    大多数语言都提供某种方法来解决这个基本问题。Java有多种方式保存对象(应该说是对象的引用)。例如前面曾经学习过的数组,它是编译器支持的类型。数组是保存一组对象的最有效的方式,如果你想保存一组基本类型数据,也推荐使用这种方式。但是数组具有固定的尺寸, 而在更一般的情况中,你在写程序时并不知道将需要多少个对象,或者是否需要更复杂的方式来存储对象,因此数组尺寸固定这一限制显得过于受限了。
    Java实用类库还提供了一套相当完整的容器类来解决这个问题。
    其中基本的类型是List、Set、Queue和Map。这些对象类型也称为集合类,但由于Java的类库中使用了Collection这个名字来指代该类库的一个特殊子集,所以我使用了范围更广的术语“容器”称呼它们。

    解读:

    1. Java保存对象的方式有:

      • 数组【可以保存基本类型数据;数组尺寸固定;只能存储同一种类型的对象】

      • 集合类【不可以保存基本类型数据;在根本上都是数组,只是可以动态改变数组的大小;结合泛型可以存储多种类型的对象】

    2. Java中的容器指Collection、Map的统称

    3. 容器中存储的是对象的引用不是对象的值;数组在存储基本数据类型时是存储的对象的值

    4. 为什么使用集合? 可以封装一组对象的操作,降低编程难度,增加代码复用性,提高程序运行速度与质量。

    2.集合中的概念

    Java容器类类库的用途是“保存对象”,并将其划分为两个不同的概念:

      1. Collection。一个独立元素的序列,这些元素都服从一条或多条规则。List必须按照插入的顺序保存元素,而Set不能有重复元素。Queue按照排队规则来确定对象产生的顺序(通常与它们被插入的顺序相同)。
      1. Map。一组成对的“键值对”对象,允许你使用键来査找值。ArrayList允许你使用数字 来査找值,因此在某种意义上讲,它将数字与对象关联在了一起。映射表允许我们使用另一个 对象来査找某个对象,它也被称为“关联数组”,因为它将某些对象与另外一些对象关联在了一 起,或者被称为“字典”,因为你可以使用键对象来査找值对象,就像在字典中使用单词来定义 一样。Map是强大的编程工具。

    什么是集合框架?

    集合框架是一个代表、操作集合的统一架构。所有的集合框架都包含以下几点:

    • 接口:表示集合的抽象数据类型。接口允许我们操作集合时不必关注具体实现,从而达到“多态”。在面向对象编程语言中,接口通常用来形成规范。

    • 实现类:集合接口的具体实现,是重用性很高的数据结构。

    • 算法:用来根据需要对实体类中的对象进行计算,比如查找,排序。 同一种算法可以对不同的集合实现类进行计算,这是利用了“多态”。重用性很高。

    3.集合的分类

    整体体系图

    Collection接口及其常用实现

    Collection接口及其常用实现

    Map接口及其常用实现

    Map接口及其常用实现

    附带Java集合最全结构展示图

    4.常用集合类与对应数据结构

    集合类是Java数据结构的实现。所以,从数据结构层面对比下集合类。

    集合 接口/类 说明
    Collection 接口 定义了集合的基本方法,
    List 接口 元素有序,元素可重复。主要实现类:ArrayList,LinkedList,Vector。
    Vector 线性表的数组实现
    Stack 栈,Last in first out,继承自Vector
    ArrayList 动态数组,源码底层维护着List的容量与实际长度
    LinkedList 双向链表,此外它还实现了Deque,即也实现了Queue
    Queue 接口 队列,First in first out
    Deque 接口 双向队列,Deque继承自Queue,并增加了首尾两端的进出队列操作
    Map 接口 一组元素结构为K、V型的集
    HashMap 哈希数组+链表,通过哈希函数能够快速地找到元素,无冲突的情况下仅需访问一次 ;1.8后哈希数组+链表+红黑树
    HashTable HashTable与HashMap的区别是其线程安全,同时它不允许K、V为null
    TreeMap Map的二叉平衡树实现,根据K的hashcode排序
    ConcurrentHashMap 线程安全的HashMap,HashTable的替代者
    Set 接口 元素无序,元素不重复。主要实现类:HashSet,TreeSet,LinkedHashSet。
    HashSet 内部使用HashMap实现,K对应E,V保存了一个Object
    TreeSet 内部由TreeMap实现,K对应E,V保存了一个Object
    LinkedHashSet 哈希表和链表的结合,且是一个双向链表;不重复且同时具有可预测的迭代顺序

    5.容器操作使用

    Collection增删改查与遍历

    作为集合的一个根接口,定义了一组对象和它的子类可以实现的方法:


    Collection.png

    对集合的基础操作,比如 :

    int size() 获取元素个数

    boolean isEmpty() 是否个数为 0

    boolean contains(Object element) 是否包含指定元素

    boolean add(E element) 添加元素,成功时返回 true

    boolean remove(Object element) 删除元素,成功时返回 true

    Iterator<E> iterator() 获取迭代器

    还有一些操作整个集合的方法,比如 :

    boolean containsAll(Collection<?> c) 是否包含指定集合 c 的全部元素

    boolean addAll(Collection<? extends E> c) 添加集合 c 中所有的元素到本集合中,如果集合有改变就返回 true

    boolean removeAll(Collection<?> c) 删除本集合中和 c 集合中一致的元素,如果集合有改变就返回 true

    boolean retainAll(Collection<?> c) 保留本集合中 c 集合中两者共有的,如果集合有改变就返回 true

    void clear() 删除所有元素

    还有对数组操作的方法:

    Object[] toArray() 返回一个包含集合中所有元素的数组

    <T> T[] toArray(T[] a) 返回一个包含集合中所有元素的数组,运行时根据集合元素的类型指定数组的类型

    在 JDK 8 以后,Collection 接口还提供了从集合获取连续的或者并行流:

    Stream<E> stream()

    Stream<E> parallelStream()

    List接口与Set接口实现Collection接口常用的方法有:

    List接口
            List接口下的集合元素存储有序,可以重复。
            List的特有功能
              A:添加功能
                  void add(int index, Object obj):在指定位置添加元素
              B:删除功能
                  Object remove(int index):根据指定索引删除元素,并把删除的元素返回。
              C:修改功能
                  Object set(int index, Object obj):把指定索引位置的元素修改为指定的值,返回修改前的值。
              D:获取功能
                  int indexOf(Object o):返回指定元素在集合中第一次出现的索引
                  Object get(int index):获取指定位置的元素
                  ListIterator listIterator():列表迭代器
              E:截取功能
                  List subList(int fromIndex, int toIndex):截取集合。
    
      Set 接口
              Set接口下的元素无序,不可以重复。其下面常用有HashSet和TreeSet。
              HashSet
               底层数据结构是哈希表,线程不安全,效率高。
               保证唯一性依赖两个方法:hashCode()和equals()。
               顺序:
                       判断hashCode()值是否相同。
                       相同:继续走equals(),看返回值
                                   如果true:就不添加到集合。
                                   如果false:就添加到集合。
                       不同:就添加到集合。
              TreeSet
                底层数据结构是二叉树,线程不安全,效率高。
                保证元素唯一性的方法时根据返回值是否是0。
                保证排序的两种方式:
                        自然排序(元素具备比较性):实现Comparable接口
                        比较器排序(集合具备比较性):实现Comparator接口
    

    遍历 Collection 的几种方式:

    for-each语法
    Collection<Person> persons = new ArrayList<Person>();
    for (Person person : persons) { 
        System.out.println(person.name);  
    }  
    
    使用 Iterator 迭代器
    Collection<Person> persons = new ArrayList<Person>();
    Iterator iterator = persons.iterator();
    while (iterator.hasNext) { 
        System.out.println(iterator.next);  
    }  
    
    使用 aggregate operations 聚合操作
    Collection<Person> persons = new ArrayList<Person>();
    persons
        .stream()
        .forEach(new Consumer<Person>() {  
            @Override  
            public void accept(Person person) {  
                System.out.println(person.name);  
            }  
    }); 
    

    Map增删改查与遍历

    map是一个键值对形式的集合。它的元素都是有键和值组成。Map的键(key)是唯一的,值(value)可以重复。

    Map的功能:

    A:添加功能
    V put(K key ,V value) :当key在集合中不存在是,添加元素;当key存在时替换元素
    
    B:判断功能
    boolean containsKey (Object key) :判断指定的键是否在集合中存在
    Boolean containsValue(Object value):判断指定的值是否在集合中存在
    Boolean isEmpty() :判断集合是否为空
    
    C:删除功能
    Void clear():清除所有键值对数据
    
    D:获取功能
    Object get (Object key) :根据键获取值
    Set<K> keyset(): 所有键的集合
    Collection<V>values() :所有值的集合
    
    E:长度功能
    Int size()
    

    Map常用的有HashMap、HashTable和TreeMap,遍历常用有3种方法:

    Map<String, Object>map = new HashMap<String, Object>();
    map.put(“test1”, object1);
    ……
    map.put(“testn” , objectn);
    

    (1).Map的values()方法可以获取Map值的集合:

    Iterator it = map.values().iterator(); 
    while(it.hasNext()){ 
      Object obj = it.next(); 
    } 
    

    (2).Map的keySet方法可以获取Map键的Set集合:

    Set<String> keys = map.keySet(); 
    for(Iterator it = key.iterator(); it.hasNext(); ){ 
      String key = it.next(); 
      Object obj = map.get(key); 
    } 
    

    (3).通过Map.entrySet使用iterator遍历key和value

    Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
    while (it.hasNext()) {
         Map.Entry<Integer, String> entry = it.next();
         System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
    }
    

    (4).通过Map.entrySet遍历key和value,推荐,尤其是容量大时

    for (Map.Entry<Integer, String> entry : map.entrySet()) {
        //entry.getKey() ;entry.getValue(); 
        System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
    }
    

    相关文章

      网友评论

        本文标题:Java基础-集合类-概述

        本文链接:https://www.haomeiwen.com/subject/ghzynktx.html