Java基础知识(九) 容器

上一篇:Java基础知识(八) Java平台与内存管理

1. Java Collections 框架是什么

Java Collections 框架中包含了大量集合接口以及这些接口的实现类和操作它们的算法(例如排序、查找、反转、替换、复制、取最小元素、取最大元素等),具体而言,主要提供了List(列表)、Queue(队列)、Set(集合)、Stack(栈)和 Map(映射表,用于存放键值对)等数据结构。其中,List、Queue、Set、Stack 都继承自 Collection 接口。Collection 是整个集合框架的基础,它里面储存一组对象,表示不同类型的 Collections,它的作用只是提供维护一组对象的基本接口而已。

下面分别介绍 Set、List 和 Map 3 个接口。

  1. Set 表示数学意义上的集合概念。其最主要的特点是集合中的元素不能重复,因此存入Set 的每个元素都必须定义 equals()方法来确保对象的唯一性。该接口有两个实现类:HashSet 和 TreeSet。其中 TreeSet 实现了 SortedSet 接口,因此 TreeSet 容器中的元素是有序的。
  2. List 又称为有序的 Collection。它按对象进入的顺序保存对象,所以它能对列表中的每个元素的插入和删除位置进行精确的控制。同时,它可以保存重复的对象。LinkedList、ArrayList 和 Vector 都实现了 List接口。
  3. Map提供了一个从键映射到值的数据结构。它用于保存键值对,其中值可以重复,但键是唯一的,不能重复。Java 类库中有多个实现该接口的类:HashMap、TreeMap、LinkedHashMap、WeakHashMap 和 IdentityHashMap。虽然它们都实现了相同的接口,但执行效率却不是完全相同的。具体而言HashMap 是基于散列表实现的,采用对象的 HashCode 可以进行快速查询。LinkedHashMap 采用列表来维护内部的顺序。TreeMap 基于红黑树的数据结构来实现的,内部元素是按需排列的。

2. 什么是迭代器

迭代器(Iterator)是一个对象,它的工作是遍历并选择序列中的对象,它提供了一种访问一个容器(container)对象中的各个元素,而又不必暴露该对象内部细节的方法。通过迭代器,开发人员不需要了解容器底层的结构,就可以实现对容器的遍历。由于创建迭代器的代价小,因此迭代器通常被称为轻量级的容器。
迭代器的使用主要有以下 3 个方面的注意事项:

  1. 使用容器的 iterator()方法返回一个 Iterator,然后通过 Iterator的 next()方法返回第一个元素。
  2. 使用 Iterator的hasNext()方法判断容器中是否还有元素,如果有,可以使用 next()方法获取下一个元素。
  3. 可以通过remove()方法删除迭代器返回的元素。

Iterator 支持派生的兄弟成员。Listlterator 只存在于 List 中,支持在迭代期间向 List 中添加或删除元素,并且可以在 List 中双向滚动。

Iterator的使用示例:

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * 描述:测试迭代器
 *
 * @author Ye
 * @version 1.0
 * @date 2021/8/11 16:50
 */
public class TestIterator {
    public static void main(String[] args) {
        List<String> students = new LinkedList<>();
        students.add("张三");
        students.add("李四");
        students.add("王五");
        for (Iterator<String> iterator = students.iterator();iterator.hasNext();){
            String str = (String)iterator.next();
            System.out.println(str);
        }
    }
}

运行截图:
在这里插入图片描述

3. ArrayList、Vector 和 LinkedList 有什么区别

ArrayList、Vector、LinkedList 类均在 java.uil 包中,均为可伸缩数组,即可以动态改变长
度的数组。

ArrayList和 Vector都是基于存储元素的 Object [] array来实现的,它们会在内存中开辟一块连续的空间来存储,由于数据存储是连续的,因此,它们支持用序号(下标)来访问元素,同时索引数据的速度比较快。但是在插人元素时需要移动容器中的元素,所以对数据的插人操作执行得比较慢。ArrayList 和 Vector 都有一个初始化的容量的大小,当里面存储的元素超过这个大小时就需要动态地扩充它们的存储空间。为了提高程序的效率,每次扩充容量,不是简单地扩充一个存储单元,而是一次增加多个存储单元。Vector 默认扩充为原来的 2 倍(每次扩充空间的大小是可以设置的),而 ArrayList 默认扩充为原来的 1. 5 倍(没有提供方法来设置空间扩充的方法)。

ArrayList 与 Vector 最大的区别就是 synchronization(同步)的使用,没有一个 ArrayList 的方法是同步的,而 Vector 的绝大多数方法(例如 add、insert、remove、set、equals、hashcode等)都是直接或者间接同步的,所以 Vector 是线程安全的,ArrayList 不是线程安全的。正是由于 Vector 提供了线程安全的机制,其性能上也要略逊于 ArrayList。

LinkedList 是采用双向列表来实现的,对数据的索引需要从列表头开始遍历,因此用于随机访问则效率比较低,但是插入元素时不需要对数据进行移动,因此插入效率较高。同时,LinkedList 是非线程安全的容器。

4. HashMap、Hashtable、TreeMap 和 WeakHashMap 有哪些区别

Java 为数据结构中的映射定义了一个接口 java. uil. Map,它包括 3 个实现类:HashMap、Hashable 和 TreMap。Map是用来存储键值对的数据结构,在数组中通过数组下标来对其内容索引的,而在 Map 中,则是通过对象来进行索引,用来索引的对象叫做 key,其对应的对象叫做 value。

HashMap 是一个最常用的 Map,它根据键的 HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。由于 HashMap 与 Hashtable 都采用了 hash 法进行索引,因此二者具有许多相似之处,它们主要有如下的一些区别:

  1. HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),它们都完成了 Map 接口,主要区别在于 HashMap 允许空(null)键值(key)(但需要注意,最多只允许一条记录的键为 null,不允许多条记录的值为 null),而 Hashtable 不允许。
  2. HashMap 把 Hashtable 的 contains 方法去掉了,改成 comtainsvalue 和 containskey,因为contains 方法容易让人引起误解。Hashtable 继承自 Dictionary 类,而 HashMap 是 Java 1.2 引进的 Mapinterface 的一个实现。
  3. Hashtable 的方法是线程安全的,而 HashMap 不支持线程的同步,所以它不是线程安全的。在多个线程访问 Hashtable 时,不需要开发人员对它进行同步,而对于 HashMap,开发人员必须提供额外的同步机制。所以,就效率而言,HashMap 可能高于 Hashtable。
  4. Hashtable 使用 Enumeration,HashMap 使用 Iterator。
  5. Hashtable 和 HashMap 采用的 hash/ rehash 算法都几乎一样,所以性能不会有很大的差异。
  6. 在 Hashtable 中,hash 数组默认大小是 11,增加的方式是 old x2+1。在 HashMap 中,
    hash 数组的默认大小是 16,而且一定是 2 的指数。
  7. hash 值的使用不同,Hashtable 直接使用对象的 hashCode。

以上 3 种类型中,使用最多的是 HashMap。HashMap里面存人的键值对在取出时没有固定的顺序,是随机的。一般而言,在 Map 中插人、删除和定位元素,HashMap 是最好的选择。由于 TreeMap 实现了 SortMap 接口,能够把它保存的记录根据键排序,因此,取出来的是排序后的键值对,如果需要按自然顺序或自定义顺序遍历键,那么 TreeMap 会更好。LinkedHashMap 是 HashMap 的一个子类,如果需要输出的顺序和输人的相同,那么用 LinkedHashMap 可以实现,它还可以按读取顺序来排列。

WeakHashMap 与 HashMap 类似,二者的不同之处在于 WeakHashMap 中 key 采用的是“弱引用”的方式,只要 WeakHashMap 中的 key 不再被外部引用,它就可以被垃圾回收器回收。

5. Collection 和 Collections 有什么区别

Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。实现该接口的类主要有 List 和 Set,该接口的设计目标是为各种具体的集合提供最大化的统一的操作方式。

Collections 是针对集合类的一个包装类,它提供一系列静态方法以实现对各种集合的搜索、排序、线程安全化等操作,其中大多数方法都是用来处理线性表。Collections 类不能实例化,如同一个工具类,服务于 Collection 框架。若在使用 Collections 类的方法时,对应的 collection 的对象为 null,则这些方法都会抛出 NullPointerException。

示例代码:

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * 描述:测试collection
 *
 * @author Ye
 * @version 1.0
 * @date 2021/8/11 20:33
 */
public class TestCollection {
    public static void main(String[] args) {
        List<Integer> list = new LinkedList<>();
        int[] array = {1,9,3,6,8};
        for (int i= 0;i<array.length;i++){
            list.add(new Integer(array[i]));
        }
        Collections.sort(list);
        for (int i=0;i<array.length;i++){
            System.out.println(list.get(i));
        }
    }
}

运行截图:
在这里插入图片描述

参考:《Java程序员面试笔试宝典》 何昊、薛鹏、叶向阳 编著

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值