Java---集合

概述

Java.util包中提供了一些集合类,这些集合又被称为容器。提到容器又会想到数组,那集合与数组之间的区别是?

集合与数组的区别:数组的长度是固定的,集合的长度是可变的;数组既可以存储基本数据类型,也可以存储引用数据类型,而集合只能存储引用数据类型;数组只能存储同一类的元素,而集合可以存储多种类型的元素。

 

可变长度数组的原理:

当元素超出数组长度,会产生一个新数组,将原数组的数据复制到新数组中,再将新的元素添加到新数组中。

ArrayList:是按照原数组的50%延长。构造一个初始容量为 10 的空列表。

Vector:是按照原数组的100%延长。

 

常用的集合有List集合,Set集合以及Map集合。其中List集合和Set集合继承了Collection接口,各接口还提供了不同的实现类。

 

Collection接口

Collection接口是层次结构中的根接口(单列集合的根接口)。构成Collection的单位称为元素,Collection接口通常不能直接使用,但该接口提供了添加元素,删除元素,管理数据的方法。由于List接口和Set接口都是继承了Collection接口,所以这些方法对List集合和Set集合都通用。

 

Collection接口的常用方法

方法

功能描述

add(E e)

将指定的对象添加到该集合中

remove(Object o)

将指定的对象从该集合中移除

isEmpty()

返回boolean值,判断当前集合是否为空

iterator()

返回在此Collection的元素上进行迭代的迭代器,用于遍历集合中的对象

size()

返回int值,获取集合中元素的个数,即集合长度

 

List集合与Set集合的区别是:List集合有序(元素存入集合的顺序与取出的顺序一致),有索引,可以存储重复元素;Set集合无序(元素存入与取出的顺序可能不一致),无索引,不可以存储重复元素,必须保证元素的唯一性。

 

在集合中,使用迭代器iterator来遍历集合,获取集合当中的元素。

例如:

 

 

List集合

List集合包括List接口以及List接口所有的实现类。List集合中的元素允许重复,各元素的顺序就是对象插入时的顺序,用户可以通过使用索引(元素在集合中的位置)来访问集合中的元素。

 

List接口

List接口继承了Collection接口,因此包含了Collection接口中的所有方法,除此之外还有新定义方法:

方法

功能描述

get(int index)

获取指定索引位置的元素

set(int index,Object o)

将集合中指定索引位置的对象修改为指定对象

addAll(index,collection)

在指定的索引位插入一堆元素

int indexOf(obj)

获取指定元素第一次出现的索引位,如果该元素不存在返回-1

int lastIndexOf(Object o)

反向索引指定元素的位置

List subList(start,end)

list集合特有的迭代器

 

注意:对于List集合,底层判断元素是否相同,其实都是使用元素自身的equals方法完成的,所以建议元素都重新复写equals方法,已建立元素对象自己比较相同的条件依据。

List接口的实现类

List接口的实现类包括ArrayList , LinkedList ,Vector。

 

ArrayList

ArrayList类实现了可变的数组,允许保存所有元素,包括null,并可以根据索引位置对集合中的元素进行快速随机访问,但由于其是指定位置来插入或删除对象,所以ArrayList增删速度慢。

ArrayList的底层数据结构是数组,线程不同步,由于底层是数组结构,而数组结构的元素在堆内存中是连续分配的,且有索引,所以查询快,增删慢。

 

 

LinkedList

LinkedList类采用链表结构保存对象。这种结构的优点是便于向集合中插入和删除对象,但查询速度慢,线程不同步。

ListedList底层是相互引用的节点组成的双向链表,当要把数据插入到该链表的某个位置时,该数据就会被组装成一个新的节点,然后只需要改变链表中要插入位置的前后的节点引用,是他们指向新的节点,即可完成插入。删除操作同样原由,只需改变节点引用即可完成。

LinkedList集合的特有方法

 

方法

功能描述

addFirst

将元素添加到链表的开头位置

addLast

将元素添加到链表的结尾位置

offerFirst(jdk1.6以后)

将元素添加到链表的开头位置

offerLast(jdk1.6以后)

将元素添加到链表的结尾位置

getFirst

获取链表中第一个元素,如果链表为空,则抛出NoSuchElementException

getList

获取链表中最后一个元素,如果链表为空,则抛出NoSuchElementException

peekFirst(jdk1.6以后)

获取链表中第一个元素,如果链表为空,则返回null

peekLast(jdk1.6以后)

获取链表中最后一个元素,如果链表为空,则返回null

removeFirst

获取链表中第一个元素,但会删除链表第一个元素,如果链表为空,则抛出NoSuchElementException

removeLast

获取链表中最后一个元素,但会删除链表最后一个元素,如果链表为空,则抛出NoSuchElementException

pollFirst(jdk1.6以后)

获取链表中第一个元素,但会删除链表第一个元素,如果链表为空,则返回null

pollLast(jdk1.6以后)

获取链表中最后一个元素,但会删除链表最后一个元素,如果链表为空,则返回null

 

 

Vector

Vector底层同样是数组结构,但是由于其线程同步,执行效率低,已经被ArrayList取代。

 

 

Set集合

Set集合中的对象不按特定的方式排序,只是简单的把对象加入到集合中,但是Set集合中不能包含重复对象。Set集合由Set接口和Set接口的实现类组成,Set接口继承了Collection接口,所以包含其所有方法。

 

Set接口

Set接口的实现类有HashSet,LinkedHashSet,TreeSet。

 

HashSet

HashSet底层是哈希表结构,线程不安全,存储取出效率高,运行速度快,但是存入与取出的顺序不一致。

HashSet集合保证元素的唯一性原理:通过元素的hashCode方法,和equals方法完成的。

当元素的hashCode值相同时,才继续判断元素的equals是否为true。如果为true,那么视为相同元素,不存。如果为false,那么存储。如果hashCode值不同,那么不判断equals,从而提高对象比较的速度。

 

哈希表的原理:

1,对对象元素中的关键字(对象中的特有数据),进行哈希算法的运算,并得出一个具体的算法值,这个值 称为哈希值

2,哈希值就是这个元素的位置。

3,如果哈希值出现冲突,再次判断这个关键字对应的对象是否相同。如果对象相同,就不存储,因为元素重复。如果对象不同,就存储,在原来对象的哈希值基础 +1顺延。

4,存储哈希值的结构,我们称为哈希表。

5,既然哈希表是根据哈希值存储的,为了提高效率,最好保证对象的关键字是唯一的。

这样可以尽量少的判断关键字对应的对象是否相同,提高了哈希表的操作效率。

 

LinkedHashSet

  LinkedHashSet继承了HashSet,是具有可预知顺序的集合,它基于哈希表与链表实现的,线程不安全,运行速度快,保证了元素的存入与取出的顺序。

 

  TreeSet

  TreeSet类不仅实现类Set接口,还实现了java.util.SortedSet接口,因此TreeSet类实现Set集合在遍历时按照自然顺序或定制顺序排序。

用于对Set集合进行元素的指定顺序排序,需要依据元素自身具备的比较性。如果元素自身不具备比较性,那么在运行时则会发生异常。所以需要实现comparable接口,复写compareTo()方法,强制让元素具备比较性。依据compareTo的返回值,确定元素在TreeSet中的位置。

TreeSet方法保证元素唯一性的方式:就是参考比较方法的结果是否为0,如果return 0,视为两个对象重复,不存。

TreeSet集合排序有两种方式,Comparable和Comparator区别:

1:让元素自身具备比较性,需要元素对象实现Comparable接口,覆盖compareTo方法。

2:让集合自身具备比较性,需要定义一个实现了Comparator接口的比较器,并覆盖compare方法,并将该类对象作为实际参数传递给TreeSet集合的构造函数。

第二种方式较为灵活。

 

 

 

Map集合

Map集合没有继承Collection接口,其提供的是Key到Value的映射,Map中不能包含相同的key,每个key只能映射到一个value。Key还决定了存储对象在映射中的存储位置,但不是有key本身对象决定,而是由一种“散列技术”进行处理的,产生一个散列码的整数值。散列码通常用作一个偏移量,该偏移量对应分配给映射的内存区域的起始位置,从而确定存储对象在映射中的存储位置。Map集合包括Map接口以及Map接口的所有实现类。

 

Map集合存储和Collection有着很大不同:

Collection一次存一个元素;Map一次存一对元素。

Collection是单列集合;Map是双列集合。

Map中的存储的一对元素:一个是键,一个是值,键与值之间有对应(映射)关系。

特点:要保证map集合中键的唯一性。

 

 

Map接口

Map接口提供了将key映射到值的对象,一个映射不能包括重复的key,一个Key最多映射到一个值。

Map集合中允许值对象是null,而且没有限制,如:map.put(“05”,null)

Map接口中的方法

方法

功能描述

put(key, V value)

向集合中添加指定的key与value的映射关系

containsKey(Object key)

如果此映射包含指定的key的映射关系,则返回true

containsValue(Object value)

如果此映射将一个或多个key映射到指定值,则返回true

get(Object key)

如果存在指定的key对象,则返回该对象对应的值,否则返回null

KeySet()

返回该集合中所有key对象,形成set集合

values()

返回该集合中所有值对象形成Collection集合

 

Map接口的实现类

Map接口的实现类有:Hashtable,HashMap,TreeMap,LinkedHashMap

 

HashMap

HashMap类是基于哈希表数据结构的Map接口实现,此实现提供所有可选的映射操作,并允许使用null值和null键,但必须保证键的唯一性。HashMap通过哈希表对其内部的映射关系进行快速查找。此类不保证映射的顺序,特别是他不保证该顺序恒久不变,线程不同步。

 

Hashtable

Hashtable底层是哈希表数据结构,是线程同步的。不可以存储null键,null值。且在jdk1.2以后,Hashtable被HashMap取代,但其子类properties仍被使用。

 

TreeMap

TreeMap不仅实现了Map接口,还实现了java.util.SortedMap接口,因此,集合中的映射关系具有一定的顺序。但在添加,删除和定位映射关系时,TreeMap类比HashMap类性能稍差。由于TreeMap类实现的Map集合中的映射关系是根据键对象按照一定的顺序排列的,所以不允许键对象为null。

可以通过HashMap类创建Map集合,当需要顺序输出时,在创建一个相同映射关系的TreeMap类实例,进行输出。

 

LinkedHashMap

在继承HashMap的同时,保证了迭代的顺序。

 

使用集合的技巧:

看到Array就是数组结构,有角标,查询速度很快。

看到link就是链表结构:增删速度快,而且有特有方法。addFirst; addLast; removeFirst(); removeLast(); getFirst();getLast();

看到hash就是哈希表,就要想要哈希值,就要想到唯一性,就要想到存入到该结构的中的元素必须覆盖hashCode,equals方法。

看到tree就是二叉树,就要想到排序,就想要用到比较。

比较的两种方式:

一个是Comparable:覆盖compareTo方法;

一个是Comparator:覆盖compare方法。

LinkedHashSet,LinkedHashMap:这两个集合可以保证哈希表有存入顺序和取出顺序一致,保证哈希表有序。

 

集合什么时候用?

当存储的是一个元素时,就用Collection。当存储对象之间存在着映射关系时,就使用Map集合。

 

保证唯一,就用Set。不保证唯一,就用List。

 

 

集合操作工具类:Collections

 

静态方法:

Collections.sort(list);//list集合进行元素的自然顺序排序。

Collections.sort(list,new ComparatorByLen());//按指定的比较器方法排序。

class ComparatorByLen implements Comparator<String>{

public int compare(String s1,String s2){

int temp = s1.length()-s2.length();

return temp==0?s1.compareTo(s2):temp;

}

}

Collections.max(list); //返回list中字典顺序最大的元素。

int index = Collections.binarySearch(list,"zz");//二分查找,返回角标。

Collections.reverseOrder();//逆向反转排序。

Collections.shuffle(list);//随机对list中的元素进行位置的置换。

 

将非同步集合转成同步集合的方法:Collections中的  XXX synchronizedXXX(XXX);

List synchronizedList(list);

Map synchronizedMap(map);

原理:定义一个类,将集合所有的方法加同一把锁后返回。

 

Collection 和 Collections的区别:

Collections是个java.util下的类,是针对集合类的一个工具类,提供一系列静态方法,实现对集合的查找、排序、替换、线程安全化(将非同步的集合转换成同步的)等操作。

Collection是个java.util下的接口,它是各种集合结构的父接口,继承于它的接口主要有Set和List,提供了关于集合的一些操作,如插入、删除、判断一个元素是否其成员、遍历等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值