Java基础——容器

参考Java程序员面试笔试宝典:

目录

1.Java Collections框架是什么

2.什么是迭代器

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

4.HashMap、Hashtable、TreeMap、WeakHashMap的区别

5.用自定义类型作为HashMap或Hashtable的key需要注意的问题

6.Collection 和 Collections 有什么区别


1.Java Collections框架是什么

Java Collections 框架包含了大量集合接口以及这些接口的实现类和操作它们的算法(如排序、查找、反转、替换、复制、取最小元素、取最大元素等)。具体而言,主要提供了List(列表)、Queue(队列)、Set(集合)、Stack(栈)和Map(映射表,存放键值对)。其中,List、Queue、Set、Stack都继承自Collection接口。

Collection 是整个集合框架的基础,储存了一组对象,表示不同类型的Collections,它的作用只是维护一组对象的基本接口。

下面简要介绍Set、List、Map3个接口。

1)Set表示数学意义上的集合概念。主要特点是集合中元素不能重复,因此存入Set的每个元素都必须定义equals()方法确保对象的唯一性。该接口有两个实现类 HashSet 和 TreeSet。其中 TreeSet 实现了 SortedSet 接口,TreeSet 容器中元素是有序的。

2)List 又称为有序的 Collection。按对象进入顺序保存对象,能对列表中每个元素的插入和删除位置进行精确的控制。同时可以保存重复对象。LinkedList、ArrayList、Vector都实现了List接口。

3)Map提供了一个从键映射到值的数据结构。它用于保存键值对,其中值可以重复,但键是唯一的。Java类库中有多个实现该接口的类:HashMap、TreeMap、LinkedHashMap、WeakHashMap、IdentityHashMap。

2.什么是迭代器

迭代器(Iterator)是一个对象,工作是遍历并选择序列中的对象,它提供了一种访问一个容器(container)对象中的各个元素,而有不必暴露该对象内部细节的方法。

通过迭代器,开发人员不需要了解容器底层的结构,就可以实现对容器的遍历。

由于创建迭代器地代价较小,通常也称为轻量级地容器。

迭代器使用注意事项:

1)使用容器 iterator() 方法返回一个Iterator,然后通过Iterator的next()方法返回第一个元素

2)使用 Iterator 的 hasNext() 方法判断容器中是否还有其他元素,如果有,可使用 next() 方法获取下一元素。

3)可通过 remove() 方法删除迭代器返回的元素。

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

public class IteratorTest {
    public static void main(String[] args) {
        List<String> ll=new LinkedList<>();
        ll.add("one");
        ll.add("two");
        ll.add("three");
        ll.add("four");
        for(Iterator<String> iter=ll.iterator();iter.hasNext();){
            String str = iter.next();
            System.out.println(str);
        }
    }
}

结果:

one
two
three
four

引申:Iterator 与 ListIterator 有什么区别?

Iterator只能正向遍历集合,适用于获取移除元素。ListIterator 继承自 Iterator,专门针对 List,可从两个方向遍历 List,同时支持元素修改。

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

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

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 是非线程安全容器。

如何选择容器?

对数据主要操作为索引或只在集合末端增删元素时,使用 ArrayList 或 Vector 效率比价高;

对数据操作主要为指定位置插入或删除操作,使用 LinkedList 效率比较高;

在多线程中使用容器(即多个线程同时访问该容器),选用 Vector 较为安全。

4.HashMap、Hashtable、TreeMap、WeakHashMap的区别

Java为数据结构的映射定义了一个接口 java.util.Map,它包括三个实现类:HashMap、Hashtable、TreeMap。Map用来存储键值对,在数组中通过数组下标对其内容索引,在 Map 中,通过对象进行索引,用来索引的对象叫key,其对于对象叫value。

HashMap 是一个最常用的 Map,根据键的 HashCode 值存储数据,根据键直接获取值,具有很快的访问速度。HashMap 与 Hashtable都采用 hash 法索引,有许多相似之处,现列出一些区别:

1)HashMap是Hashtable的轻量级实现(非线程安全实现),都完成了Map接口,区别在于 HashMap 允许空(null)键值(key),但最多只允许一条记录的键为 null,不允许多条;而 Hashtable 不允许。

2)HashMap 把 Hashtable 的 contains 方法去掉了,改成containsvalue 和 containskey,因为contains方法容易让人误解。Hashtable继承自Dictionary 类,而HashMap 是Java 1.2 引进的 Map interface 的一个实现。

3)Hashtable是线程安全的,而HashMap不支持线程同步,不是线程安全,当多线程访问时,需要开发人员提供额外同步机制。因此就效率而言,HashMap 可能高于 Hashtable。

4)Hashtable 使用 Enumeration,HashMap使用 Iterator。

5)HashMap 和 Hashtable采用的 hash/rehash 算法几乎一样,所以性能不会有很大的差异。

6)Hashtable中,hash默认数组大小为11,增加方式为old*2+1;在 HashMap 中,hash默认数组大小为16,且一定是2的指数。

7)hash值的使用不同,Hashtable直接使用对象的hashCode。

以上三种类型HashMap使用最多,存入的键值对取出时顺序随机。一般而言,在Map中插入、删除、定位元素,HashMap是最好的选择。

TreeMap实现了SortMap接口,能将保存的记录根据键排序,因此,取出是排序后的键值对,若需要按自然顺序或自定义顺序遍历键,TreeMap会更好。

LinkedHashMap是HashMap的一个子类,若需要输出顺序和输入相同,则使用LinkedHashMap,它可按读取顺序排列。

WeakHashMap与HashMap类似,不同之处在于WeakHashMap中的key采用“弱引用”,只要WeakHashMap中的key不再被外部引用,就可被垃圾回收器回收;而HashMap中的key采用“强引用”方式,当HashMap中的key没被外部引用,只有这个key从HashMap中删除,才能被垃圾回收器回收。

笔试题:

1.在Hashtable上下文中,同步指的是什么?

同步意味着一个时间点只能有一个线程可以修改hash表,任何线程在执行Hashtable的更新操作前需要获取对象锁,其他线程需等待锁的释放。

2.如何实现HashMap的同步?

HashMap通过 Map m = Collections.synchronizedMap(new HashMap()) 来达到同步效果。具体而言,该方法返回一个同步Map,该Map封装了底层的HashMap所有方法,使得底层的HashMap即使在多线程环境也是安全的。

5.用自定义类型作为HashMap或Hashtable的key需要注意的问题

1)如果想根据对象的相关属性来自定义对象是否相等的逻辑,此时需要重写equals()方法,一旦重写equals()方法,就要重写hashCode()方法。

2)当自定义类的多项作为HashMap或Hashtable的key时,最好把这个类设计为不可变类。

3)从HashMap工作原理看,如果两个对象相等,那么两个对象有着相同的hashCode,反之不成立。

6.Collection 和 Collections 有什么区别

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

Collections 是针对集合类的一个包装类,它提供了一系列静态方法以实现对各种集合的搜索、排序、线程安全化等操作,其中大多数方法用来处理线性表。

Collections 不能实例化,如同一个工具类,服务于 Collection 框架。若在使用 Collections 类的方法时,对应的 Collection 的对象为null,会抛出 NullPointerException。

使用Collections示例:

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

public class Test{
    public static void main(String[] args) {
        List<Integer> list = new LinkedList<>();
        int array[] = {7,3,5,1};
        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));
        }
    }
}

结果:

1
3
5
7

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值