Java集合类:collection和map接口

时间:2020-12-14 16:59:53

一、集合类简介

数组是很常用的一种的数据结构,我们用它可以满足很多的功能,但是,有时我们会遇到如下这样的问题:

1、我们需要该容器的长度是不确定的。

2、我们需要它能自动排序。

3、我们需要存储以键值对方式存在的数据。

如果遇到上述的情况,数组是很难满足需求的,接下来本章将介绍另一种与数组类似的数据结构——集合类,集合类在Java中有很重要的意义,保存临时数据,管理对象,泛型,Web框架等,很多都大量用到了集合类。

常见的集合类有这些种:

实现Collection接口的:Set、List以及他们的实现类。

实现Map接口的:HashMap及其实现类,HashTable,SortedMap ,我们通过一个图来整体描述一下:

Java集合类:collection和map接口

下面的表格也许可以更直接的表现出他们之间的区别和联系:

接口

简述

实现

操作特性

成员要求

Set

成员不能重复

HashSet

外部无序地遍历成员

成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。

TreeSet

外部有序地遍历成员;附加实现了SortedSet, 支持子集等要求顺序的操作

成员要求实现caparable接口,或者使用 Comparator构造TreeSet。成员一般为同一类型。

LinkedHashSet

外部按成员的插入顺序遍历成员

成员与HashSet成员类似

List

提供基于索引的对成员的随机访问

ArrayList

提供快速的基于索引的成员访问,对尾部成员的增加和删除支持较好

成员可为任意Object子类的对象

LinkedList

对列表中任何位置的成员的增加和删除支持较好,但对基于索引的成员访问支持性能较差

成员可为任意Object子类的对象

Map

保存键值对成员,基于键找值操作,compareTo或compare方法对键排序

HashMap

能满足用户对Map的通用需求

键成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。

TreeMap

支持对键有序地遍历,使用时建议先用HashMap增加和删除成员,最后从HashMap生成TreeMap;附加实现了SortedMap接口,支持子Map等要求顺序的操作

键成员要求实现caparable接口,或者使用Comparator构造TreeMap。键成员一般为同一类型。

LinkedHashMap

保留键的插入顺序,用equals 方法检查键和值的相等性

成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。

IdentityHashMap

使用== 来检查键和值的相等性。

成员使用的是严格相等

WeakHashMap

其行为依赖于垃圾回收线程,没有绝对理由则少用

 


二、基本方法及使用

---------------------------

实现Map接口的

HashMap

Set的实现类HashSet,底层还是调用Map接口来处理,所以,此处,我将说下Map接口及其实现类的一些方法。Map接口中的原始方法有:

public abstract int size();
public abstract boolean isEmpty();
public abstract boolean containsKey(Object paramObject);
public abstract boolean containsValue(Object paramObject);
public abstract V get(Object paramObject);
public abstract V put(K paramK, V paramV);
public abstract V remove(Object paramObject);
public abstract void putAll(Map<? extends K, ? extends V> paramMap);
public abstract void clear();
public abstract Set<K> keySet();
public abstract Collection<V> values();
public abstract Set<Entry<K, V>> entrySet();
public abstract boolean equals(Object paramObject);

public abstract int hashCode();


实现Collection接口的

ArrayList

ArrayList底层采用数组实现,具有较高的查询速度。

boolean isEmpty():如果容器里面没有保存任何元素,就返回true。

boolean contains(Object):如果容器持有参数Object,就返回true。

Iterator iterator():返回一个可以在容器的各元素之间移动的Iterator。

Object[] toArray():返回一个包含容器中所有元素的数组。

Object[] toArray(Object[] a):返回一个包含容器中所有元素的数组,且这个数组不是普通的Object数组,它的类型应该同参数数组a的类型相同(要做类型转换)。

void clear():清除容器所保存的所有元素。(“可选”)

boolean remove(Object o);

boolean add(Object):确保容器能持有你传给它的那个参数。如果没有把它加进去,就返回false。(这是个“可选”的方法,本章稍后会再作解释。)

boolean addAll(Collection):加入参数Collection所含的所有元素。只要加了元素,就返回true。

boolean containsAll(Collection):如果容器持有参数Collection所含的全部元素,就返回true

boolean removeAll(Collection):删除容器里面所有参数Collection所包含的元素。只要删过东西,就返回true。(“可选”)

 boolean retainAll(Collection):只保存参数Collection所包括的元素(集合论中“交集”的概念)。如果发生过变化,则返回true。(“可选”)

boolean equals(Object o);

int hashCode();

int size():返回容器所含元素的数量。

这些方法也就是Set和List及它们的实现类里有的方法。

List接口在Collection接口的基础上,有添加了自己的一系列方法:

E get(int index);

E set(int index, E element);

void add(int index, E element);

E remove(int index);

int indexOf(Object o);

int lastIndexOf(Object o);

ListIterator<E> listIterator();

ListIterator<E> listIterator(int index);

List<E> subList(int fromIndex, int toIndex);


LinkedList

LinkedList底层采用双向循环列表实现,进行插入和删除操作时具有较高的速度,我们还可以使用LinkedList来实现队列和栈。

可以参考学习这篇博客 http://blog.csdn.net/sinat_36246371/article/details/53709625


三、比较(性能,功能方面)

这一块主要就是对我们平时接触的这些集合类做一个简单的总结,一方面有助于自己整理思路,再者面试的时候,面试官总喜欢问一些他们之间的区别,凡是Java面试,几乎都要问到集合类的东西,问的形式有两种:一、总体介绍下集合类有哪些。这个问题只要把我上文中的图介绍一下就行了。二、比较一下XXX和XXXX。当然了,肯定包括相同点和不同的地方。这个稍微麻烦一点,需要我们彻底理解了,才能回答的比较准确。以下是我对常被比较的一些类的分析:

1、HashMap和HashTable

      相同点:二者都实现了Map接口,因此具有一系列Map接口提供的方法。

      不同点:

            1、HashMap继承了AbstractMap,而HashTable继承了Dictionary。

            2、HashMap非线程安全,HashTable线程安全,到处都是synchronized关键字。

            3、因为HashMap没有同步,所以处理起来效率较高。

            4、HashMap键、值都允许为null,HashTable键、值都不允许有null。

            5、HashTable使用Enumeration,HashMap使用Iterator。

      这些就是一些比较突出的不同点,实际上他们在实现的过程中会有很多的不同,如初始化的大小、计算hash值的方式等等。毕竟这两个类包含了很多方法,有很重要的功能,所以其他不同点,请感兴趣的读者自己去看源码,去研究。笔者推荐使用HashMap,因为她提供了比HashTable更多的方法,以及较高的效率,如果大家需要在多线程环境中使用,那么用Collections类来做一下同步即可。

2、Set接口和List接口

  相同点:都实现了Collection接口

    不同点:

          1、Set接口不保证维护元素的顺序,而且元素不能重复。List接口维护元素的顺序,而且元素可以重复。

       2、关于Set元素如何保证元素不重复,我将在下面的博文中给出。

3、ArrayList和LinkList

     相同点:都实现了Collection接口

      不同点:ArrayList基于数组,具有较高的查询速度,而LinkedList基于双向循环列表,具有较快的添加或者删除的速度,二者的区别,其实就是数组和列表的区别。上文有详细的分析。

4、SortedSet和SortedMap

二者都提供了排序的功能。

5、TreeMap和HashMap

     HashMap具有较高的速度(查询),TreeMap则提供了按照键进行排序的功能。

6、HashSet和LinkedHashSet

     HashSet,为快速查找而设计的Set。存入HashSet的对象必须实现hashCode()和equals()。

     LinkedHashSet,具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序),于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。

7、TreeSet和HashSet

     TreeSet: 提供排序功能的Set,底层为树结构 。相比较HashSet其查询速度低,如果只是进行元素的查询,我们一般使用HashSet。

8、ArrayList和Vector

      同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的。

      数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半

9、Collection和Collections

      Collection是一系列单值集合类的父接口,提供了基本的一些方法,而Collections则是一系列算法的集合。里面的属性和方法基本都是static的,也就是说我们不需要实例化,直接可以使用类名来调用。下面是Collections类的一些功能列表: