集合笔记

Collection接口

一、概述


二、Collection接口

Collection接口的方法:

		boolean add(Object o): 向集合中添加一个元素,成功返回true。
		
		boolean addAll(Collection c): 将集合c总所有元素添加至指定集合。
		
		void clear(): 清空集合元素。
		
		boolean contains(Object o ): 判断好似否包含该元素。
		
		boolean contains(Collection c): 判断集合中是否包含集合c中所有元素。
		
		Iterator  iterator(): 返回一个iterator对象,用于遍历该集合。
		
		boolean isEmpty():判断集合是否为空。
		
		boolean remove(Object o): 删除集合中指定元素。
		
		boolean removeAll(Collection c):删除集合c中所有元素。
		
		int size(): 返回集合中元素个数。
		
		Object[] toArray(): 将集合转换为数组。
	

Iterator接口

主要用于遍历Collection集合中的元素,Iterator必须依附于Collection对象,Iterator仅用于遍历集合,本身并不提供承装对象的能力。当使用Iterator遍历Collection集合时,Collection集合中元素不能被修改,但可以被删除。

boolean hasNext(): 如果仍有元素可以迭代,则返回 true。

Object next(): 应将Java迭代器认为是位于两个元素之间的。当调用next()时,迭代器就越过下一个元素,并返回刚刚越过的那个元素的引用。

void remove(): 将会删除上次调用next()方法时返回的元素。如果需要删除指定位置上的元素,仍然需要先越过这个元素。

例如删除指定集合中第一个元素的方法:
		Collection<Integer> c = new ArrayList<> ();
		c.add(36);
		c.add(12);
		Iterator<Integer> it = c.iterator();
		it.next();
		it.remove();

注意:对于next方法和remove方法的调用具有相互依赖性,如果调用remove之前没有调用next是不合法的。只有对自然有序的集合使用迭代器添加元素才有意义,而像set类型,其中的元素完全无序。因此,在Iterator接口中就没有add方法。

三、Set接口

【Set接口】

		Set里面元素是无序的,不允许包含相同元素。
		
		Set集合中判断两个对象相同不使用==运算符,而是使用equals函数。

HashSet类

一种没有重复元素的无须集合。

HashSet是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素。HashSet实现原理:http://zhangshixi.iteye.com/blog/673143

HashSet是按Hash算法来存储集合中的元素,具有很好的存取和查询性能。

HashSet不能保证元素的排列顺序,顺序可能与添加顺序不同。

HashSet不是同步的。

HahsSet元素值可以是null。

HashSet判断两个元素相等的标准是:两个对象的equals()方法比较相等,并且两个对象的hashCode()方法返回值也相同。因此在把某个类的对象保存到HashSet集合中,重写这个类的equals方法返回true时,它们的hashCode方法返回值也相等。

LinkedHashSet类

一种可以记住元素插入次序的集。

LinkedHashSet与HashSet的不同之处在于,LinkedHashSet维护着一个双向链表,该链表定义了迭代顺序:插入顺序和访问顺序。

LinkedHashSet继承于HashSet,又基于LinkedHashMap来实现。LinkedHashSet底层构造了一个LinkedHashMap来实现,在相关操作上与父类HashSet相同。

LinkedHashSet也是根据元素的hashCode值来决定元素的存储位置,但它同时使用链表来维护元素的次序。当遍历LinkedHashSet时,LinkedHashSet将会按元素的添加顺序来访问集合中的元素。<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>

TreeSet类

TreeSet可以确保集合元素处于排序状态。

TreeSet与HashSet采用hash算法决定元素的存储位置不同,TreeSet采用红黑树的数据结构来存储元素。

TreeSet支持两种排序方法:自然排序和定制排序。

对象的比较:
1)TreeSet如何知道希望元素怎样排列呢?在默认情况下,树集假定插入的元素实现了Comparable接口,该接口定义了一个方法:

int compareTo(T other);   如String类便实现了Comparable接口,它的compareTo方法依据字典序对字符串进行比较。

 如果要将自定义的对象插入到TreeSet中,就必须实现Comparable接口,示例如下:

class Demo implements Comparable
{
	public int x;
	public int y;
	public Demo(int x)
	{
		this.x = x;
	}
	public int compareTo(Object obj)
	{
		Demo other = (Demo)obj;
		return this.x - other.x;
	}
}
2)使用Comparable接口定义排序显然有其局限性。对于一个给定的类,只能实现这个接口一次。如果在一个集合中需要按x进行排序,在另一个集合中需要按y进行排序,该怎么办呢?另外,如果需要对一个类的对象进行排序, 而该类的创建者并没有实现Comparable接口,又该怎么办呢?这种情况下,可以通过将Comparator对象传递给TreeSet的构造器来告诉树集使用不同的比较方法。示例如下:
class Demo implements Comparable
{
	public int x;
	public int y;
	
	public Demo()
	{};
	
	public Demo(int x,int y)
	{
		this.x = x;
		this.y = y;
	}
	public int compareTo(Object obj)
	{
		Demo other = (Demo)obj;
		return this.x - other.x;
	}
}
public class Test{  
	
	public static void main(String[] args) throws Exception
	{
		Demo d1 = new Demo(2,6);
		Demo d2 = new Demo(4,7);
		Demo d3 = new Demo(5,3);
		Demo d4 = new Demo(1,8);
		Demo d5 = new Demo(9,0);
		Set<Demo> set = new TreeSet<> (new Comparator<Demo> ()
				{
					public int compare(Demo d1,Demo d2)
					{
						return d1.y -d2.y;
					}
				});
		set.add(d1);
		set.add(d2);
		set.add(d3);
		set.add(d4);
		set.add(d5);
		for(Demo d : set)
			System.out.println("x :" + d.x + "," + "y:" + d.y);
	}   
}

【EnumSet类】

EnumSet中所有元素都必须是指定枚举类型的枚举值。

EnumSet集合元素是有序的,EnumSet以枚举值在Enum类内的定义顺序决定集合元素的顺序。

EnumSet内部以向量的形式存储。

EnumSet集合不允许加入null值。

EnumSet没有构造器来实现,需通过它提供的static方法来创建EnumSet对象。

 

四、List接口

List接口方法:

		List集合是元素有序、可重复的,每个元素都有对应索引。
		
		与Set相比,List增加了根据索引来插入、替换和删除元素的方法。
		
		List通过equals()方法返回true判断两个对象相等。
		boolean add(E e):列表尾添加指定元素。
		
		void add(int index,E element):在列表指定位置插入元素。
		
		E get(int index):返回列表中指定位置元素。
		
		int indexOf(Object o):返回列表中第一次出现的元素的索引,没有的话返回-1。
		
		lastIndexOf(Object o):返回列表中最后出现的元素索引。
		
		Iterator<E> iterator():按适当顺序返回迭代器。
		
		ListIterator<E> listIterator():返回一个列表迭代器,以便用来访问列表中的元素。
		
		size():返回列表中元素。
		
		.......

 

ListIterator接口

		List除了iterator()方法外,还提供了listIterator()方法。
		
		ListIterator接口继承Iterator接口,提供了专门操作List方法:hasPrevious()、previous()、add()。
		
		与Iterator相比,增加了向前迭代功能,还可通过add向List集合添加元素(Iterator只能删除元素)。

【ArrayList类和Vector类】

二者都是基于数组实现的List类,所以ArrayList类和Vector类封装了一个动态的、允许再分配的Object[]数组。

二者在用法上几乎完全相同,但Vector太古老,不建议使用。

【固定长度的List】

有一个操作数组工具类:Arrays,该类提供了asList(Object…a)方法,该方法可以把一个数组或者指定个数的对象转换成一个List集合,该List集合既不是ArrayList实现类的实例,也不是Vector实现类的实例,而是Arrays的内部类ArrayList的实例。

Arrays.ArrayList是一个固定长度的List集合,程序只能遍历集合里的元素,不可增加、删除。

 

 

五、Queue接口

Queue用于模拟队列这种数据结构。 队列可以让人们有效的在尾部添加一个元素,在头部删除一个元素。有两个端头的队列,即双端队列,可以让人们在头部和尾部同时添加或删除元素,但不支持在队列中间添加元素。它的两个实现类ArrayDeque类、LinkedList都提供了双端队列。

	boolean add(E element)
	boolean offer(E element)
	如果队列没有满,将给定的元素添加到这个队列的尾部并返回true;如果队列满了,第一个方法将抛出异常,第二个方法返回false。
	
	E remove()
	E poll()
	如果队列不空,删除并返回这个队列头部的元素。如果队列是空的,第一个方法抛出异常,第二个方法返回null。
	
	E element()
	E peek()
	如果队列不空,返回队列头部的元素,但不删除。如果队列空,第一个方法抛出异常,第二个方法返回null。
	

Deque接口

是Queue接口的子接口,代表一个双端队列。

Deque定义了一些双端队列的方法,这些方法允许从两端来操作队列中元素。

这样,Deque不仅可以当成当成双端队列使用,还可以被当成栈来使用。

void addFirst(E element)
void addLast(E element)
boolean offerFirst(E element)
boolean offerLast(E element)
将给定的对象添加到双端队列的头部或尾部。如果队列满了,前面两个方法将抛出异常,后面两个方法返回false。

E removeFirst()
E removeLast()
E pollFirst()
E pollLast()
如果队列不空,删除并返回队列头部的元素。如果队列为空,前面两个方法将抛出异常,后面两个方法返回null。

E getFirst()
E getLast()
E peekFirst()
E peekLast()
如果队列为空,返回队列头部的元素,但不删除。如果队列空,前面两个方法将抛出异常,后面两个方法返回null。

PriorityQueue类

      一种允许高效删除最小元素的集合。
   PriorityQueue中的元素可以按照任意的顺序插入,却总是按照排序的顺序就行检索。无论何时调用remove方法,
总会获得当前优先级队列中最小的元素。优先级队列使用的数据结构是堆。
      与TreeSet一样,一个优先级队列既可以保存实现了Comparable接口的类对象,也可以保存在构造器上提供比较器的对象。
      使用优先级队列的典型示例是任务调度。每个任务都有优先级,任务以随机顺序添加到队列中。每当启动一个新的任务时,豆浆优
先级最高的任务从队列中删除(习惯上将"1"设置为最高优先级)。

【ArrayDeque类】

是Deque的一个典型实现类。

是一个基于数组实现的双端队列,创建队列时刻指定Object[]数组长度。

 

【LinkedList类】

是List接口的实现类,可根据索引来随机访问集合中元素,可被当成双端队列来使用。

是Deque接口的实现类,可被当成栈来使用。

 

 

Map接口

 

一、概述

 


Map用于保存具有映射关系的数据,因此Map集合里保存着两组值,一组值用于保存Map里的key,一组值用于保存Map里的value。Map中的key不允许重复。Map也被称为字典,或关联数组。

Set与Map之间关系密切:Map中的key没有顺序,key与key之间不能重复。从java源码来看,Java是先实现了Map,然后通过包装一个所有value都为null的Map就实现了Set。实际上Map确实包含了一个keySet()方法,用于返回Map里所有key组成的Set集合。

如果把Map里的所有value放在一起来看,它们类似于List:元素之间可以重复,每个元素可以根据索引来查找,只是Map中的索引不再是整数值,而是以另一个对象作为索引。

	V get(Object key)
	获取与键对应的值或对象
	
	V put(K key,V value)
	将键与对应的值关系插入到映射表中。如果这个键已经存在,新的value将会取代旧的value。
	
	boolean containsKey(Object key)
	如果在映射表中已经有这个键,返回true。
	
	boolean containsValue(Object value)
	如果在映射表中已经有这个值,返回true。
	
	Set<Map.Entry<K, V>> entrySet()
	返回Map.Entry对象的集视图。可以从这个集合中删除元素,同时也从映射表中删除了该元素。但不能添加元素。
	
	Set<K> keySet()
	返回映射表中所有键的集视图。可以从这个集合中删除元素,同时也从映射表中删除了该元素。但不能添加元素。

	Collection<V> values()
	返回映射表中所有值的集视图。可以从这个集合中删除元素,同时也从映射表中删除了该元素。但不能添加元素。

HashMap类

一种存储键/值关联的数据结构。

HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。它的底层就是一个数组,数组中的每一项又是一个链表。当创建一个HashMap的时候,就会初始化一个

数组。HashMap的底层实现原理:http://zhangshixi.iteye.com/blog/672697

<strong>HashMap与Hashtable的关系</strong>

都是Map接口的典型实现类,二者关系类似ArrayList和Vector的关系。

HashMap可以使用null作为key或value,Hashtable不允许使用null作为key和value。

HashMap不是线程同步的,Hashtable是线程同步的。

HashMap的父类是AbstractMap类,Hashtable的父类是Dictionary类。

二者判断key相等的标准类似于HashSet:两个key通过equals()方法比较返回true,两个key的hashCode值也相同。

LinkedHashMap类

一种可以记住键/值项添加次序的映射表。当条目插入到表中,就会并入到双向链表中。

LinkedHashMap继承于HashMap,因而底层实现也是数组+链表,不同的是,LinkedHashMap的链表是一个双向链表,该链表定义了条目的顺序:插入顺序和访问顺序,默认是插入顺序。

LinkedHashMap的底层实现原理:http://zhangshixi.iteye.com/blog/673789

要实现访问顺序,可以调用构造方法:LinkedHashMap<K,V>(initialCapacity,loadFactor,true)  。  每次调用get或put,受到影响的条目将从当前的位置删除,并放到条目链表的尾部(只有条目在链表中的位置会受影响,而散列表中的同不会受影响。一个条目总位于与键散列码对应的桶中)。   

访问顺序对于实现高速缓存的LRU(即:最近最少使用)原则十分重要。我们可能希望将访问频率高的元素放在内存中,而将近期最少使用的元素从内存中移除。我们可以让这一过程自动化。方法如下:

构造一个LinkedHashMap的子类,然后覆盖removeEldestEntry方法,每当方法返回true时,就添加一个新条目,从而导致删除eldest的条目。示例:

下面的高速缓存可以存放10个元素:

Map<K,V>  cache = new MyLinkedHashMap<>(128,0.75f,true)
{
	protected boolean removeEldestEntry(<Map.Entry<K,V>>  eldest)
	{
		return size() > 10;
	}
};

操作集合的工具类:Collections

 

 

是操作Set、List、Map等集合的工具类,实现对集合元素的排序、查找、修改等操作。

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值