这一节我们来总结一下Java集合类。

Java集合总结
  继承与Collection接口的–List接口
    List接口本身的特点
    常见的继承List接口的实用类
    实用类对比
  继承与Collection接口的–Set接口
    Set接口本身的特点
    常见的继承Set接口的实用类
    实用类对比
  继承与Collection接口的–Queue接口
    Queue接口本身的特点
    常见的继承Queue接口的实用类
  特例独立的–Map接口
    Map接口本身的特点
    常见的继承Map接口的实用类
    实用类对比
  操作集合的工具类:Collections

Java集合总结

  Java集合是每个Java程序员在日常开发中都会使用到,而且有时候使用得好的话,能事半功倍。细数Java集合,其实比较常见的就是List、Set、Map和Queue,在这四者之中,除了Map之外,其他三个接口都继承于Collection。 
  在这里,首先我们要明确的是,List、Set、Map和Queue其实只是以接口的形式存在着的,所以在日常的程序开发中,请不要出现说想要直接初始化它们的想法和做法,虽然笔者也曾经犯过这样子的错误。

继承与Collection接口的–List接口

List接口本身的特点

  List接口在Java的集合类中充当的是一个元素有序、元素可重复的集合角色。List继承于Collection集合,故其拥有了Collection集合的全部方法,同时,List集合也拥有属于自己的方法:用来实现根据元素索引来操作集合元素的作用。通过List集合的源码(JDK1.7)我们简单地看看List集合包含的方法:

package java.util;
public interface List extends Collection { int size(); //集合元素的数量
boolean contains(Object o); //是否包含某变量,包含返回ture
Iterator<E> iterator();
Object[] toArray(); //将集合转化为一个数组,所有的集合元素变成相应的数组元素
<T> T[] toArray(T[] a); //将集合转化为一个类型T数组
boolean add(E e); //增加元素,成功返回true
boolean remove(Object o); //移除元素,成功返回true
boolean containsAll(Collection<?> c); //是否包含集合c中的全部元素,若是返回true
boolean addAll(Collection<? extends E> c); //添加整个集合c中全部元素,
boolean addAll(int index, Collection<? extends E> c);
boolean removeAll(Collection<?> c); //移除该List集合中包含的c中的全部元素
boolean retainAll(Collection<?> c); //是否包含c集合中的元素,包含返回ture
void clear(); //清空集合
boolean equals(Object o);
int hashCode();
E get(int index); //根据index取元素值
E set(int index, E element); //根据index把List该元素重新复制element
void add(int index, E element); //根据index添加新元素element
E remove(int index);
int indexOf(Object o); //返回对象o在List集合中第一次出现的位置索引
int lastIndexOf(Object o); //返回对象o在List集合中最后一次出现的位置索引
ListIterator<E> listIterator();
ListIterator<E> listIterator(int index);
List<E> subList(int fromIndex, int toIndex); //截断集合 }

常见的继承List接口的实用类

  • ArrayList 
      ArrayList是基于数组实现的List类,故其封装了一个动态的、允许再分配的Object[]数组,ArrayList用initialCapacity参数来设置该数组的长度,当长度超过预设值后,ArrayList会动态增加。 
    ArrayList类是线程不安全的,如果要保证该集合的同步性,必须在程序中手动保证。 
    值得注意的是:虽说与以链表形式建立的LinkedList相比,ArrayList()的插入和修改速度较慢,但那个也是建立在数据量较大的情况下的,在数据量较小的情况下,ArrayList()不一定比LinkedList()方法要慢。另外,ArrayList在末尾插入和删除数据的话,速度反而比LinkedList要快
  • LinkedList 
      LinkedList(): 在实现中采用链表数据结构。插入和删除速度快,访问速度慢。 
    因为除了继承List接口外,LinkedList接口也继承了Deque接口,故也可以当作“栈”和队列(双向队列)来使用。因此LinkList接口也会多出一些Deque接口方面的方法,如offer()(将元素接到队列的尾部)、push()或offerFirst()(将元素加入栈的顶部)、peek()或peekFirst()(访问但是不删除栈顶元素)、pop()或者pollLast()(将栈顶元素弹出栈)等方法。
  • Vector 
      Vector与ArrayList十分地相像,都是基于数组实现的List类,其也是封装了一个动态分配的Object[]数组,也可以使用initialCapacity参数来设置该数组的长度。 
    Vector是线程安全的,但是也因此Vector的性能很差。
  • Stack 
      Stack是继承与Vector的子类,它主要用来模拟”栈“,因此也具备了peek()、pop()、push()等主要用于栈操作的方法。 
      由于Stack是一个比较古老的Java集合类,它同样是线程安全的,但也因此暴露出了性能较差的缺点,如果程序中要使用栈这样的数据结构的话,可以试一试ArrayDeque,该类也是List的实现类,但和LinkedList一样也继承了Deque接口。

实用类对比

分类 ArrayList LinkedList Vector Stack
实现形式 动态数组 链表 动态数组 动态数组
线程安全性 线程不安全 线程不安全 线程安全 线程安全
优点 性能较高,随机访问速度快 插入和删除速度快 线程安全 线程安全
缺点 插入与删除元素的速度慢 随机访问速度访问速度慢 性能较差 性能较差

使用List集合有以下建议: 
1、遍历集合元素。ArrayList和Vector使用get()方法来获取遍历元素,LinkedList应该采用迭代器来遍历集合元素。 
2、插入和删除。当这类操作较多的时候,优先考虑使用LinkedList。 
3、多线程。当需要使用到多线程的ArrayList时,可以使用Collections将该集合类包装成线程安全的集合。

继承与Collection接口的–Set接口

Set接口本身的特点

  Set代表的是无序的、不可重复的集合。因此在Set集合中加入数据元素时,Set集合通常不用记住元素的添加顺序。不可重复则是说当将两个相同的元素加入到一个Set集合中,则添加操作失败,add()方法返回false,且新元素不会被添加。

public interface Set extends Collection {

int size();                             //集合元素的数量

boolean isEmpty();                      //判断集合是否为空

boolean contains(Object o);              //是否包含某变量,包含返回ture

Iterator<E> iterator();

Object[] toArray();

<T> T[] toArray(T[] a);

boolean add(E e);

boolean remove(Object o);

boolean containsAll(Collection<?> c);              //是否包含c集合中的元素,包含返回ture

boolean addAll(Collection<? extends E> c);         //添加包含c集合中所有的元素,包含返回ture

boolean retainAll(Collection<?> c);                 

boolean removeAll(Collection<?> c);

void clear();

boolean equals(Object o);

int hashCode();

}

常见的继承Set接口的实用类

  • HashSet 
    HashSet按照Hash算法来存储集合中的元素,因此具有良好的存取和查找功能。 
    HashSet有三个特点:与TreeSet不同,HashSet是无序的;不是线程同步;集合元素可以是null值。 
    HashSet集合的存储过程:当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该值决定该对象在HashSet中的存储位置。如果有两个元素通过equals()方法返回true,但他们的hashCode()方法返回值不相等,HashSet也会将其存储在不同的位置。也就是说:HashSet的添加元素判断标准是:两个对象通过equals()方法比较相等,并且两个对象的hashCode()方法返回值也相等。
  • LinkedHashSet 
    LinkedHashSet是继承于HashSet的子类。 
    但是与父类不同的是,LinkedHashSet用以链表的形式来维护元素的次序,也就是说:LinkedHashSet是有序的。遍历该集合时输出顺序为添加顺序。
  • TreeSet 
    TreeSet是SortedSet接口的实现类,所以TreeSet可以确保集合元素处于排序状态。TreeSet使用红黑树来维护集合元素的次序。如果实现comparator()方法,可以实现定制排序。如果采用自然排序,则返回null。 
    TreeSet集合的特有方法:first()、last()、lower(Object e)(返回指定元素之前的元素)、higher(Object e)(返回指定元素之后的元素)等等。 
    下面我们说一说TreeSet的定制排序和自然排序: 
    1、 定制排序 
    通过Comparator接口的帮助,实现降序排序。 
    2、 自然排序 
    TreeSet通过CompareTo(Object obj)比较元素之间的大小关系,将集合元素按升序排列。实现元素必须实现Comparable元素,而且在比较的时候如果出现不同类型时要转换类型后比较。
  • EnumSet 
    EnumSet是专门为枚举类设计的集合类,EnumSet中的所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式或隐式地指定。 
    EnumSet在内部以位向量的形式存储,十分紧凑、高效,因此EnumSet对象占用内存很小,且运行效率很高。但是该集合元素中不允许加入null元素。

实用类对比

分类 HashSet LinkedHashSet TreeSet EnumSet
实现形式 Hash存储 链表+Hash存储 红黑树 枚举类型(位向量)
线程安全性 线程不安全 线程不安全 线程不安全 线程不安全
优点 插入和删除速度快 集合元素有序,插入和删除速度较快 集合元素有序,插入和删除速度较快 批量操作速度较快,性能最好
缺点 集合元素无序 (链表)性能较差 (红黑树)性能较差 只能用来存储枚举类型

继承与Collection接口的–Queue接口

Queue接口本身的特点

Queue用来模拟队列这种数据结构,故其拥有add()、element()、offer()、peek()、poll()、remove()等方法。

package java.util;
public interface Queue extends Collection { boolean add(E e); //在队尾增加元素e boolean offer(E e); //在队尾增加元素e E remove(); //获取队列头部的元素,并移除该元素 E poll(); //获取队列头部的元素,并移除该元素 E element(); //获取队列头部的元素,但不移除该元素 E peek(); //获取队列头部的元素,但不移除该元素 }

常见的继承Queue接口的实用类

  • PriorityQueue 
    PriorityQueue是Queue的标准队列实现类。PriorityQueue不是按照加入队列的顺序进行排列的,而是根据队列大小进行重新排序的(升序),这一点要特别注意的。 
    PriorityQueue中不允许插入null元素,它也有两种排序方式:自然排序(实现Comparable接口,且为同一个类比较)和定制排序(建立对象时传入一个Comparator对象)。这个部分和TreeSet的要求基本一致。
  • Deque–ArrayDeque 
    首先要说明的是:Deque是Queue的子接口,代表的是双向链表,故该接口中也定义了一些方法来从两端来操作队列的数据。 
    ArrayDeque:是一个基于数组实现的双端队列,它与ArratList的实现体制很相像,都会采用了动态可再分配的数组来存储集合元素。但是其在用途上主要是被当作”栈“来使用。
  • Deque–LinkedList 
    LinkedList在上述已表述过。与ArrayDeque不同的是,LinkedList是使用链表实现的。

特例独立的–Map接口

Map接口本身的特点

  Map与上述三个接口不同的是,该接口无法继承于Collection接口,主要原因还是因为Map是用来存储具有映射关系的数据,所以Map中保存着两组值。一组值用来保存Map中的Key,另外一组用来保存Map里的value。值得注意的是:Map中的key不能重复。判断标准是同一个Map对象的任何两个key通过equals方法比较总是返回false。

package java.util;

public interface Map {

int size();

boolean isEmpty();

boolean containsKey(Object key);              //是否包含key值,如果是返回true

boolean containsValue(Object value);          //是否包含value值,如果是返回true

V get(Object key);                            //根据key值获取相应的value值

V remove(Object key);                         //根据key值从集合中移除相应的value值

void putAll(Map<? extends K, ? extends V> m); //将指定的m中的key-value复制到该集合中

void clear();

Set<K> keySet();                              //返回该Map中所有key组成Set集合

Collection<V> values();                       //返回该Map中所有的value组成的Collection

Set<Map.Entry<K, V>> entrySet();              //返回Map中包含的key-value对所组成的Set组合,每个集合元素都是Map.Entry对象。

interface Entry<K,V> {

    K getKey();                               //返回该Entry里面包含的key值

    V getValue();                             //返回该Entry里面包含的value值

    V setValue(V value);                      //设置原本的value值并返回该值

    boolean equals(Object o);

    int hashCode();
} boolean equals(Object o); int hashCode(); }

Map与Set相似度极高,将Map中的key和value分离开来看。key组是使用set集合方法来存储的。不仅如此,在子类的实现方面,两者也有很多的相似,所以你也会发现两者子类的命名很相像。

常见的继承Map接口的实用类

  • HashMap 
    HashMap是线程不安全的实现,且HashMap中可以使用null作为key或者value。
  • LinkedHashMap 
    LinkedHashMap使用一个双向链表来维护key-value对的次序,其也是一个有序的Map集合,顺序与key-value对的插入顺序保持一致。
  • TreeMap 
    TreeMap是一个红黑树的结构,每个key-value作为红黑树的一个节点。TreeMap也会对key进行排序,也分为自然排序和定制排序两种。
  • EnumMap 
    EnumMap是一个与枚举类一起使用的Map实现。
  • HashTable 
    HashTable是一个比较古老的Map实现类,它是一个线程安全的Map实现,且不允许使用null作为key和value。由于该类是比较久远的类,其性能较低,所以现在用的也比较少。 
    HashTable判断value相等的标准是:value与另外一个对象通过equals()方法返回true即可。

实用类对比

  一般的应用场景,使用HashMap已经够用了。它非常适合于快速查询。但是如果程序需要一个排序的Map集合,可以考虑使用TreeMap。

操作集合的工具类:Collections

  Java提供了一个操作Set、List和Map等集合的工具类:Collections,该类提供了大量的方法对集合元素进行排序、查询和修改等操作,还提供了将集合对象设置为不可变、对集合对象实现同步控制。

    • 排序:reverse()(反转集合元素顺序)、shuffle()(随机排列)、sort()、swap()等方法。
    • 查找和替换:binarySearch(list,obj)(二分查找指定List集合元素obj的索引)、max()、min()、fill()、frequency()(返回指定集合元素的出现次数)、replaceAll()等方法。
    • 同步控制:Collections提供了多个synchronizedXxx()方法,该方法可以将指定的集合包装成线程同步的集合,进而解决了多线程并发访问集合时的线程安全问题。
    • 设置不可变集合:Collections提供三个方法来返回一个不可变的集合:emptyXxx()(返回一个空的、不可变的集合对象)、singletonXxx()、unmodifiableXxx()方法。

Java语法总结--Java集合类的更多相关文章

  1. IT兄弟连 Java语法教程 Java语言入门 典面试题

    1.请说明JVM.JRE和JDK是什么?它们有什么关系? JVM是Java虚拟机,Java Virtual Machine的缩写,是一个虚构出来的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实 ...

  2. IT兄弟连 Java语法教程 Java开发环境 JVM、JRE、JDK

    要想开发Java程序,就需要知道什么是JVM.JRE以及JDK.JVM是运行Java程序的核心,JRE是支持Java程序运行的环境,而JDK是Java开发的核心,下面我们分别具体介绍它们以及它们之间的 ...

  3. IT兄弟连 Java语法教程 Java平台的版本划分

    自从Sun公司推出Java以来,就力图使之无所不能.Java发展至今,按应用范围划分为3个版本,即Java SE.Java EE和Java ME,也就是SunOne(Open Net Environm ...

  4. IT兄弟连 Java语法教程 Java语言的其他特性

    Java语言中除了非常重要的跨平台特性外,还有如下几个关键特性: ●  语法简单易学 Java语言的语法简单明了,容易掌握,而且是纯面向对象(OOP)的语言,Java语言的简单性主要体现在以下几个方面 ...

  5. IT兄弟连 Java语法教程 Java的发展历程

    只有少数几种编程语言对程序设计带来过根本性的影响.其中,Java的影响由于迅速和广泛而格外突出.可以毫不夸张的说,1995年Sun公司发布的Java1.0给计算机程序设计领域带来了一场变革.这场变革迅 ...

  6. IT兄弟连 Java语法教程 Java开发环境 配置Java环境变量

    在安装完JDK后,我们需要配置系统的环境变量,否则在控制台中使用JDK为我们提供的工具时将出现如图12所示的错误信息. 图12  未配置环境变量时执行java命令提示的错误信息 当出现这样的提示信息时 ...

  7. IT兄弟连 Java语法教程 Java开发环境 安装JDK

    因为我们要开发Java程序,所以必须在我们的计算机中安装Sun(Oracle)公司提供给我们的JDK.目前最新版本的JDK是JDK 10,但是我们以学习JDK 8为主,所以我们要安装的版本是JDK 8 ...

  8. IT兄弟连 Java语法教程 Java语言的跨平台特性

    什么是平台 Java是可以跨平台的编程语言,那么首先我们需要知道什么是平台,通常我们把CPU与操作系统的整体称为平台. CPU大家都知道,是计算机的大脑,它既负责思维运算,又负责计算机中各种零部件的命 ...

  9. IT兄弟连 Java语法教程 Java语言背景

    驱使计算机语言革新的因素有两个:程序设计技术的改进和计算环境的改变.Java也不例外.在大量继承C和C++的基础之上,Java还增加了反应当前程序设计技术状态的功能与精华.针对在线环境的蓬勃发展(In ...

随机推荐

  1. 广商博客冲刺第二天new

    队名:雷锋队 队员:叶子鹏 王佳宁 张奇聪 张振演 曾柏树 项目:广商博客(嵌入APP) 执笔人:王佳宁 第一天沖刺傳送門 第三天沖刺傳送門 今天主要是写需求分析,在经过组员的热烈地讨论,需求分析如下 ...

  2. JQuery基础-- Ajax

    基本格式: get: $.get("url",data,function(res){   #.....   }) post: $.post("url",data ...

  3. #Leetcode# 977. Squares of a Sorted Array

    https://leetcode.com/problems/squares-of-a-sorted-array/ Given an array of integers A sorted in non- ...

  4. Java与JavaScript之间关于JSON的是非恩怨

    http://blog.csdn.net/joyhen/article/details/43271569 js 单引号替换成双引号,双引号替换成单引号 操作 解决问题的场景: Java端生成了JSON ...

  5. ASP.NET MVC用户登录(Memcache存储用户登录信息)

    一.多站点共享用户信息解决方案: 采用分布式缓存Memcache模拟Session进行用户信息信息共享 1.视图部分

  6. python 深入浅出装饰器(decorator)--举的例子关于星级争霸2(starcraft2)

    其实早就想写一篇深入浅出装饰器的文章,苦于一直没有找到很好的例子描述,自己除了在写api参数检测和日志打印的时候用到以外,其他地方也没有什么重度使用所以一直没有写. 我不会讲解装饰器的理论,还有各种基 ...

  7. 如何隐藏Win7登录界面的administrator用户名恢复

    很多朋友一直在用着第三方的Windows7系统盘来装机,例如下载了Ghost格式的一些装机盘.在这些第三方系统中,很多家都是默认使用administrator 帐户自动登陆的. 从安全的角度来讲,这样 ...

  8. rabbitmq线上服务器与项目结合的问题总结

    一.特殊字符需要转义 只需要加个\反斜杠就可以了 二.zk的connectString 在rabbit web页面上登录上去,新增queue就可以了

  9. python之Oracle操作(cx_Oracle)

    python可通过使用cx_Oracle模块对Oracle数据库进行操作.首先,需要下载cx_Oracle模块,下载地址:https://pypi.python.org/pypi/cx_Oracle/ ...

  10. input 的 oninput onkeypress onkeydown onchange 事件的区别

    事件执行顺序: <input type="text" id="foo" onkeydown="console.log('down')" ...