Bootstrap

java集合笔记分享

集合 

前言

集合:集合是java中提供的一种容器,可以用来存储多个数据。集合和数组既然都是容器,它们有啥区别呢?

集合和数组的区别:

    数组的长度是固定的。集合的长度是可变的。

    数组中存储的是同一类型的元素,可以存储基本数据类型值。集合存储的都是对象。而且对象的类型可以不一致。在开发中一般当对象多的时候,使用集合进行存储。

集合概述

(1)集合是存储其他对象的特殊对象。可以将集合当做一个容器。

(2)集合的相关接口和类位于java.util包中

(3)集合中的接口和类是一个整体、一个体系。

集合框架

    Collection:单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是java.util.List和java.util.Set。

    List的特点是元素有序、元素可重复。

Set的特点是元素无序,而且不可重复。

List接口的主要实现类有java.util.ArrayList和java.util.LinkedList,

    Set接口的主要实现类有java.util.HashSet和java.util.TreeSet。

12.2  集合接口

接口定义了一组抽象方法,实现该接口的类需要实现这些抽象方法,从而实现接口的类就具备了接口所规定的行为(功能)。

集合框架定义了一些接口,它们决定了集合类的本质特性。具体的集合类只是提供了标准接口的不同实现。

接  口

描  述

Collection

允许操作一组对象,它位于集合层次结构的顶部

List

扩展Collection,以处理序列(对象列表)

Set

扩展Collection,以处理组,组中的元素必须唯一

注意:

Set类型的集合(实现Set接口的类)称为集,有些资料称为组,其特点是组中的元素必须唯一。

12.2.1  Collection接口

Collection接口是构建集合框架的基础,Collection是泛型接口,其声明如下:

interface Collection,

其中,E指定了集合将存储的对象类型。

提示:

l 集合中只能存储对象,不能存基本类型。

l 使用泛型的优点是在编译时可以检查元素的类型,从而更加安全。

Collection接口扩展了Iterable接口。这意味着所有集合都可以使用for-each风格的for循环进行遍历。

方  法

描  述

boolean add(E obj)

将obj添加到调用集合。

boolean addAll(Collection c)

将c中的所有元素添加到调用集合中。

boolean remove(Object obj)

从调用集合中删除obj的一个实例。

boolean removeAll(Collection c)

从调用集合中删除c的所有元素。

void clear()

删除调用集合中的所有元素

boolean contains(Object obj)

如果obj是调用集合的元素,则返回true。

boolean isEmpty()

如果调用集合为空,则返回true。

int size()

返回调用集合中元素的数量

Iterator iterator()

返回调用集合的一个迭代器

containAll(Collection c)

提示:

1、Collection接口中没有提供修改元素的方法。

2、Collection接口的父接口是Iterable接口,实现了Iterable接口的类是可以迭代的。

Collection 常用功能

Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合。方法如下:

public boolean add(E e): 把给定的对象添加到当前集合中 。 public void clear() :清空集合中所有的元素。 public boolean remove(E e): 把给定的对象在当前集合中删除。 public boolean contains(E e): 判断当前集合中是否包含给定的对象。 public boolean isEmpty(): 判断当前集合是否为空。 public int size(): 返回集合中元素的个数。 public Object[] toArray(): 把集合中的元素,存储到数组中。

import java.util.ArrayList; import java.util.Collection; ​ public class Demo1Collection { public static void main(String[] args) { // 创建集合对象 // 使用多态形式 Collection<String> coll = new ArrayList<String>(); // 使用方法 // 添加功能 boolean add(String s) coll.add("小李广"); coll.add("扫地僧"); coll.add("石破天"); System.out.println(coll); ​ // boolean contains(E e) 判断o是否在集合中存在 System.out.println("判断 扫地僧 是否在集合中"+coll.contains("扫地僧")); ​ //boolean remove(E e) 删除在集合中的o元素 System.out.println("删除石破天:"+coll.remove("石破天")); System.out.println("操作之后集合中元素:"+coll); // size() 集合中有几个元素 System.out.println("集合中有"+coll.size()+"个元素"); ​ // Object[] toArray()转换成一个Object数组 Object[] objects = coll.toArray(); // 遍历数组 for (int i = 0; i < objects.length; i++) { System.out.println(objects[i]); } ​ // void clear() 清空集合 coll.clear(); System.out.println("集合中内容为:"+coll); // boolean isEmpty() 判断是否为空 System.out.println(coll.isEmpty()); } }

12.2.2  List接口

List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操作集合的特有方法,如下:

public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。

    public E get(int index):返回集合中指定位置的元素。

    public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。

    public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。

List接口扩展了Collection,并且声明了存储一连串元素的集合的行为。在列表中,可以使用从0开始的索引,通过它们的位置插入或访问元素。列表可以包含重复的元素。其声明如下:

interface List

方  法

描  述

void add(int index, E obj)

将obj插入到index所指定的位置。

boolean addAll

(int index, Collection c)

将c的所有元素插入到index所指定的位置。

E remove(int index)

删除index位置的元素

E set(int index, E obj)

将index所指定位置的元素设置为obj

E get(int index)

返回指定索引处存储的对象

int indexOf(Object obj)

返回第一个obj实例的索引。

int lastIndexOf(Object obj)

返回列表中最后一个obj实例的索引

ListIterator listIterator()

返回一个迭代器,该迭代器从列表的开头开始

ListsubList(int start,int end)

返回一个子列表。

注意:

List接口中操作元素的方法许多都提供了index参数,这是与Collection接口中所提供相关方法的主要区别。

12.2.4  Set接口

Set接口定义了组/集/集合(set)。它扩展了Collection接口,并声明了不允许重复元素的集合的行为。如果为集合添加重复的元素,add()方法会返回false。声明如下:

interface Set

Set接口没有添加自己的方法。

SortedSet接口扩展了Set接口,并且声明了以升序进行排序的集合的行为。

Set集合有多个子类,主要使用java.util.HashSet、java.util.LinkedHashSet这两个集合。

// Set集合取出元素的方式可以采用:迭代器、增强for。

// 不能用普通的for循环,因为是无序的,没有U索引/下标。

interface SortedSet

SortedSet定义了一些便于进行集合处理的方法。例如,为了获得集合中的第一个对象,可以调用first()方法。为了得到最后一个元素,可以使用last()方法。

NavigableSet接口扩展了SortedSet接口,并且该接口声明了支持基于最接近匹配原则检索元素的集合行为。

注意:

Set相关接口表示的集合没有索引的概念。

12.3  集合类

描  述

ArrayList

动态数组

LinkedList

链表

ArrayDeque

双端队列 = 队列 + 堆栈

PriorityQueue

支持基于优先级的队列

HashSet

使用哈希表存储元素的组

LinkedHashSet

扩展HashSet类,以允许按照插入的顺序进行迭代

TreeSet

实现存储于树中的集合。

12.3.1  Arraylist类

ArrayList实现了List接口。ArrayList集合数据存储的结构是数组结构。本质上是元素为对象引用的长度可变的数组。

元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList是最常用的集合。

构造方法:

l ArrayList( )  //长度取默认值 10

l ArrayList(int capacity)  //指定长度,容量

泛型:

T :代表一般的任何类。

E :代表 Element 元素的意思,或者 Exception 异常的意思。

K :代表 Key 的意思。

V :代表 Value 的意思,通常与 K 一起配合使用。

12.3.2  LinkedList类

LinkedList类实现了List、Deque以及Queue接口。它提供了(双向)链表数据结构。

LinkedList具有两个构造方法:

LinkedList( )

LinkedList(Collection c)

ArrayList(顺序列表)

 List listname = new ArrayList();

LinkedList(链式列表)

 List listname = new LinkedList();

ArrayList与LinkedList的区别:

1、ArrayList是基于数组结构的集合,有容量的概念;LinkedList是基于链表结构的集合,没有容量的概念

2、对于随机访问(get和set方法),ArrayList优于LinkedList,因为LinkedList要移动指针。

3、对于新增和删除操作(add和remove方法),LinkedList比较占优势,因为ArrayList要移动数据。但是如果只是在末尾追加元素,效率差不多。

4、LinkedList 还实现了Queue接口,该接口比List提供了更多的方法,包括 offer(),peek(),poll()等。

12.3.3  HashSet

HashSet类实现了Set接口。该类在内部使用哈希表存储元素。

哈希表使用称之为散列法(hashing)的机制存储信息。哈希法的优点是add()、contains()、remove()以及size()方法的执行时间保持不变,即使是对于比较大的集合也是如此。

HashSet( )  //默认容量是16

HashSet(int capacity)

HashSet(int capacity, float fillRatio)  //填充率:0.0-1.0之间,默认0.75

HashSet(Collection c)

HashSet中元素不是按有序的顺序存储的,遍历输出HashSet中的元素时精确的输出可能不同。

初始容量 倒是好理解,顾名思义,初始容量只是哈希表在创建时的容量,那么** 加载因子** 到底是表示什么意思呢?

如果按术语来讲: 加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。如果当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行rehash()操作,从而哈希表将具有大约两倍的桶数。

还不是很懂???

其实说白了加载因子 就是一个比例值。

例子:

比如说向水桶中装水,此时HashMap就是一个桶, 这个桶的容量就是加载容量,而加载因子就是你要控制向这个桶中倒的水不超过水桶容量的比例,比如加载因子是0.75 ,那么在装水的时候这个桶最多能装到3/4 处,超过这个比例时,桶会自动扩容。因此,这个桶最多能装水 = 桶的容量 * 加载因子。

如果桶的容量是16,加载因子是0.75 那么你的桶最多能装16*0.75 = 12的水,如果你装了12的水还想继续装水,那么就该用大一点的桶,调用rehash就是负责增加桶的容量的方法,当然这个rehash这个方法是内部调用的。

12.3.4  LinkedHashSet类

LinkedHashSet类扩展了HashSet类,它没有添加它自己的方法。

LinkedHashSet在内部使用一个链表维护元素添加到集合中的顺序,因此可以按照插入顺序迭代集合。

12.3.4  TreeSet类

TreeSet类实现了NavigableSet接口,该类在内部使用树结构存储元素。元素以升序存储,访问和检索相当快。TreeSet适合于存储大量的、必须能够快速查找到的有序信息。

Set与List的区别:

1、Set中的元素无序不能重复,List中的有序元素可以重复。

2、List有索引(下标)的概念,Set没有索引的概念。

3、对于Set表示的集合,通常是遍历操作,没有get()和set()方法。

注意:

TreeSet以升序保存对象,所以TreeSet中保存的对象比较能够比较大小,即TreeSet保存的对象类型必须实现Comparable接口。

注意:

HashSet是无序的,LinkedHashSet和TreeSet是有序的。

集合遍历

12.4.1 Iterable接口

实现了Iterable接口的类是可以遍历的。因为Iterable接口是Collection接口的父接口,而所有集合类都实现了Collection接口,从而也都实现了Iterable接口,所以所有集合类都是可以遍历的。

Iterable接口只定义了一个方法:

Iterator  iterator()  //返回迭代器对象

既然所有集合都实现了Iterable接口,所以所有集合类都重写了iterator()方法以返回一个迭代器对象。

12.4.2  Iterator接口

Iterator接口描述了迭代器的行为,所有迭代器类都必须实现该接口,该接口定义了一下方法:

l boolean  hasNext()   如果迭代还有更多的元素则返回true

l T  next()            返回下一个元素

l void  remove()       删除迭代器返回的元素

提示:

从Iterator接口定义的方法不难看出Iterator只能从前向后进行遍历。

12.4.3  ListIterator接口

Iterator接口有一个子接口ListIterator,ListIterator接口即可以从前向后遍历,也可以从后向前遍历集合。只有实现了List接口的集合类才提供了ListIterator迭代器。

List接口提供以下两个方法用于获取列表集合的列表迭代器:

ListIterator listIterator()  该迭代器从列表的开头开始

ListIterator listIterator(int index)  该迭代器从index所指定的位置开始

ListIterator接口定义了以下常用方法。

l boolean  hasNext()

l Boolean  hasPrevious()

l E  next()

l int  nextIndex()

l E  previous()

l int  previousIndex()

12.4.1  使用迭代器

通常,为了使用迭代器遍历集合的内容,需要以下步骤:

1.通过调用集合的Iterator()方法,获取指向集合开头的迭代器。

2.建立一个hasNext()调用循环。只要hasNext()返回true,就循环迭代。

3.在循环中,通过调用next()获取每个元素。

对于实现了List接口的集合,还可以调用listIterator()获取迭代器。列表迭代器提供了向前和向后两个方向访问集合的能力,并且允许修改元素。

12.4.2  增强的for循环

如果不修改集合的内容,也不以反向获取元素,则使用for-each版的for循环遍历集合通常比使用迭代器更方便。

迭代器与增强的for循环之间的区别:

使用迭代器遍历集合时,可以调用Iterator.remove()方法删除集合中元素,使用增强的for循环遍历集合时,不能删除集合中的元素。

可以使用增强的for循环遍历数组,但是数组不支持迭代器。

使用增强的for循环遍历基本类型的数组时,只能使用数组元素,而不能修改数组元素。

12.5  Collections工具类

12.5.1  Collections类里面包括动态、有序、可变大小的一维数组Vector与ArrayList。

Collections提供以下方法对List进行排序操作

void reverse(List list):反转

void shuffle(List list),随机排序

void sort(List list),按自然排序的升序排序

void sort(List list, Comparator c);定制排序,由Comparator控制排序逻辑

void swap(List list, int i , int j),交换两个索引位置的元素

12.6  遗留的集合类和接口(选)

在集合之前,Java提供了特定的类,存储和管理对象组,例如Dictionary、Vector、Stack和Properties。

早期版本的java.util包没有包含集合框架。反而,定义了几个类和接口,提供存储对象的专门方法。当添加集合时(由J2SE 1.2添加),对几个原始类进行了重新设计,以支持集合接口。因此,从技术上讲它们现在是集合框架的组成部分。

前面介绍的所有现代集合类都不是同步的,但是所有遗留类都是同步的。

12.5.1  Vector类

现在Vector类实现了动态数组,与ArrayList类似,也实现List接口。但有如下区别:

l Vector实现同步,线程安全。ArrayList没有实现线程安全。

l Vector性能比ArrayList低。

l Vector和ArrayList在更多元素添加进来时会请求更大的空间。Vector每次请求其大小的双倍空间,而ArrayList每次对size增长50%.

;