Java集合容器详解

目录

 

一、Java集合框架概述

二、使用 Iterator接口遍历Collection 集合元素

三、foreach遍历集合和数组

四、Collection接口的子接口——List接口

五、Collection接口的子接口——Set接口

六、Map接口及其多个实现类


一、Java集合框架概述

Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的 关联数组。Java 集合可分为 Collection 和 Map 两种体系。
 

1、Collection接口:单列数据,定义了存取一组对象的方法的集合。

  • List元素有序、可重复的集合。
  • Set元素无序、不可重复的集合。
2、Map 接口: 双列数据,保存具有映射关系“ key-value 对”的集合。
 

Java集合容器详解_第1张图片

二、使用 Iterator接口遍历Collection 集合元素

Iterator : Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素。

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * @author hedong
 * @version 1.0
 * @date 2020/4/9 18:56
 */
public class CollectionTest {
    public static void main(String[] args) {
        //new一个具体的实现类
        Collection c1 = new ArrayList();
        //往集合中添加三个数据
        c1.add("hedong");
        c1.add("zhangsan");
        c1.add("liming");

        //返回c1的迭代器
        Iterator iterator = c1.iterator();
        //遍历集合
        while(iterator.hasNext()){//hasNext():判断是否还有下一个元素
            Object obj = iterator.next();//next():指针下移 ,将下移以后集合位置上的元素返回
            System.out.println(obj);
        }
    }
}

注意:hasNext()仅判断是否还有下一个元素,只有执行了next()指针才会下移并返回该位置上的元素。

三、foreach遍历集合和数组

Java 5.0 提供了 foreach 循环迭代访问 Collection和数组
 
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * @author hedong
 * @version 1.0
 * @date 2020/4/9 18:56
 */
public class CollectionTest {
    public static void main(String[] args) {
        //new一个具体的实现类
        Collection c1 = new ArrayList();
        //往集合中添加三个数据
        c1.add("hedong");
        c1.add("zhangsan");
        c1.add("liming");
        
        //foreach内部任然是使用的iterator实现
        //for(要遍历元素类型 局部变量:需要遍历的集合对象)
        for (Object obj:c1) {
            System.out.println(obj);
        }

    }
}

注意:foreach遍历方式内部仍然使用Iterator迭代器实现

四、Collection接口的子接口——List接口

List接口是Collection接口的子接口,它包括三个常用实现类:ArrayListLinkedListVector。List集合是有序的,可重复的。

ArrayList和LinkedList的异同:
  二者都线程不安全,相对线程安全的Vector,执行效率高。
此外,ArrayList底层 是基于动态数组的数据结构, LinkedList基于链表的数据结构。对于
随机访问get set ArrayList 觉得优于 LinkedList ,因为 LinkedList要移动指针。对于新增
和删除操作add( 特指插入 ) remove LinkedList 比较占优势,因为 ArrayList要移动数据。 
ArrayList和Vector的区别:
Vector和 ArrayList 几乎是完全相同的 , 唯一的区别在于 Vector 是同步类 (synchronized),属于
强同步类。因此开销就比ArrayList 要大,访问要慢。正常情况下 , 大多数的 Java程序员使用
ArrayList而不是 Vector, 因为同步完全可以由程序员自己来控制。 Vector每次扩容请求其大
小的2 倍空间,而 ArrayList 1.5 倍。 Vector 还有一个子类 Stack。

五、Collection接口的子接口——Set接口

Set接口是Collection接口的子接口,它包括三个常用实现类:HashSetLinkedHashSet(HashSet的子类)TreeSet。Set集合是无序的,不可重复的。

注意:这里的“无序”不是说每次Set集合打印出来的元素顺序都不一样,而是,每次往Set集合中存放元素时,元素并不是根据底层数组索引顺序存放的,存放位置由哈希值决定。同理,List集合中所谓的“有序”是指元素是根据底层数组索引顺序存放。也就是说,有序或者无序是针对添加时而言。

  • HashSet:Set接口的主要实现类,是线程不安全的,可存储null值。
  • LinkedHashSet:是HashSet的子类,遍历其内部数据时可按照添加时顺序输出。(注意:这并不意味着“有序”)
  • TreeSet:可根据添加对象的指定属性进行排序。所以TreeSet集合中添加的数据必须为相同类的对象

添加元素的过程(以HashSet为例):

1、向HashSet集合中添加元素a

2、调用元素a所在类的hashCode()方法,计算a的哈希值

3、根据计算的哈希值再调用某种算法计算出在HashSet底层数组中的存放位置,即索引位置

4、判断该位置上是否已经有了元素

  • 若该位置没有其他元素:直接添加元素a成功
  • 若该位置已经有了其他元素b:则比较元素a和b的哈希值,若哈希值不相同,则添加元素a成功;若哈希值相同,则调用元素a所在类的equals()方法,若返回true,则添加失败,返回false,则添加成功。

注意:如果位置上已经有了元素,后面在这个位置上继续添加的元素将以链表方式存储。

六、Map接口及其多个实现类

Map集合用于存储双列数据,即key——value数据。他包括HashMap、LinkedHashMap、TreeMap、Hashtable、Properties多个实现类。

  • HashMap:Map的主要实现类,线程不安全、高效,key和value可以为null。
  • LinkedHashMap:HashMap的子类,可以在遍历Map元素时按照添加时的顺序输出。
  • TreeMap:可以进行排序。
  • Hashtable:Map古老的实现类,线程安全,效率低,key和value不可以为null。
  • Properties:Hashtable的子类,常用于处理配置文件,key和value都是string类型。

Map结构的理解:

  • map中的key:无序的、不可重复的,使用Set存储key。
  • map中的value:无序的,可重复的,使用Collection存储value。
  • map中的Entry:一个键值对key—value构成一个Entry对象,无序的,不可重复的,使用Set存储Entry对象。

HashMap底层实现原理:

实例化Map对象后,底层将创建一个Entry 数组,当添加一个元素(key-value)时,就首先计算元素key的hash值,以此确定插入数组中的位置,如果这个位置没有元素,则插入成功;如果这个位置已经有了元素,则比较它们的哈希值,如果哈希值不同,则以链表的形式链在这个元素旁边;如果哈希值也相同,则调用equals()比较,若为false,则同样以链表的形式链在旁边,若为true,则覆盖它的值。

你可能感兴趣的:(Java)