java基础----集合框架

集合框架

1.集合框架的体系结构
集合–集中合并数据----文件夹是一个集合的表现
统一管理/处理数据
框架–jdk提供操作类库
集合框架–jdk提供的对集中合并数据进行统一管理/处理的开发类库。

交由集合统一管理/处理的数据有两种表现形式:
单列数据【独立的一个数据–数字,字符串,…】
100 ,”hello”
键值对数据 【一个数据是由键和建对应的值组成】
书的目录就是一种典型的键值对数据
【标题:页码】
Jdk提供的处理单列数据的开发类库
Collection接口是Jdk提供的处理单列数据的顶级接口。
Collection接口的子接口List接口处理有顺序的单列数据。
List接口可以有重复的数据元素,按照顺序区分。
ArrayList类
LinkedList类
Collection接口的子接口Set接口处理没有顺序的单列数据。
Set接口不能有重复的数据元素,【重复的元素被视为同一个】
HashSet类
LinkedHashSet类
在这里插入图片描述

2.Conllection与Map
Collection接口
1.List接口
List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。和下面要提到的Set不同,List允许有相同的元素。除了具Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。
1)ArrayList
ArrayList实现了可变大小的数组,它允许所有元素,包括null。size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间,其他的方法运行时间为线性。
每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小,这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。和LinkedList一样,ArrayList也是非同步的(unsynchronized)。
2)LinkedList
LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque),可以认为LinkedList在方法和逻辑上和ArrayList是一样的,只是在性能上有一定的区别,ArrayList适合随机访问LinkedList更适合插入和删除,在对性能没有很大要求是是可以忽略这个差别的。
   注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
    List list = Collections.synchronizedList(new LinkedList(…));
3)Vector
Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和ArrayList创建的Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。
ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存操作,所以索引数据快插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快!
4)Stack
Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
2.Set接口
Set是一种不包括重复元素的Collection。它维持它自己的内部排序,所以随机访问没有任何意义。与List一样,它同样运行null的存在但是仅有一个。由于Set接口的特殊性,所有传入Set集合中的元素都必须不同,同时要注意任何可变对象,如果在对集合中元素进行操作时,导致e1.equals(e2)==true,则必定会产生某些问题。实现了Set接口的集合有:EnumSet、HashSet、TreeSet。
1)HashSet
HashSet堪称查询速度最快的集合,因为其内部是以HashCode来实现的。它内部元素的顺序是由哈希码来决定的,所以它不保证set 的迭代顺序,特别是它不保证该顺序恒久不变。
2)TreeSet
基于TreeMap,生成一个总是处于排序状态的set,内部以TreeMap来实现。它是使用元素的自然顺序对元素进行排序,或者根据创建Set 时提供的Comparator进行排序,具体取决于使用的构造方法。
3)LinkedHashSet
底层是链表实现的,是set集合中唯一一个能保证怎么存就怎么取的集合对象,因为是HashSet的子类,所以也是保证元素唯一的,与HashSet的原理一样。
3.Queue接口
1)阻塞式队列(BlockingQueue):队列满了以后再插入元素则会抛出异常,主要包括ArrayBlockQueue、PriorityBlockingQueue、LinkedBlockingQueue。
2)双端队列(Deque):支持在头、尾两端插入和移除元素,主要包括:ArrayDeque、LinkedBlockingDeque、LinkedList。

Map接口
Map与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到Value的映射。同时它也没有继承Collection。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同。实现map的有:HashMap、TreeMap、Hashtable、Properties、EnumMap。
1)HashMap
HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。,但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。
2)TreeMap
键以某种排序规则排序,内部以red-black(红-黑)树数据结构实现,实现了SortedMap接口
3)Hashtable
Hashtable继承Dictionary类实现Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。添加数据使用put(key,value),取出数据使用get(key),这两个基本操作的时间开销为常数。
Hashtable通过initial capacity和load factor两个参数调整性能。通常缺省的load factor 0.75较好地实现了时间和空间的均衡。增大load factor可以节省空间但相应的查找时间将增大,这会影响像get和put这样的操作。Hashtable是同步的.

3.List与Set
List和Set是用来存放集合的接口,并且二者都继承自接口Collection。
在List中的元素存放是有序的,可以存放重复的元素,检索效率较高,插入删除效率较低。
ArrayList、LinkedList、Vector是List的两个实现类。
ArrayList:
底层的实现就是一个可变数组非同步实现,当数组长度不够用的时候就会重新开辟一个新的数组,然后将原来的数据拷贝到新的数组内。由于这一底层实现,所以ArrayList集合中元素存储的位置是连续的,查询起来效率比较高,插入删除效率较低。
LinkedList:
底层实现是双向循环链表数据结构非同步实现,数据结构如下代码

class Node 
{
  private Node privious;//引用前一个节点
  private Object value;//当前节点的value值
  private Node next;//引用下一个节点的值
}

LinkList中元素存储位置是不连续的,插入删除的执行效率高,查询效率低。
Vector:
Vector作为List的另外一个典型实现类,完全支持List的全部功能,Vector类也封装了一个动态的,允许在分配的Object[]数组,Vector是一个比较古老的集合,JDK1.0就已经存在,建议尽量不要使用这个集合,Vector与ArrayList的主要是区别是,Vector是线程安全的,但是性能比ArrayList要低。
set没有存放顺序不能存放重复元素检索效率较低,插入删除效率较高,由于set集合储存位置是由他的HashCode码决定的,所以他的存储对象必须有equals()方法,而且set遍历只能用迭代,没有下标。
HashSet:
底层由哈希表(实际上是一个HashMap实例)支持,不能保证元素的顺序,元素是无序的,可以有null,但是null只能有一个,不能有重复的元素。HashSet不是同步的,需要外部保持线程之间的同步问题。
TreeSet:
TreeSet实现了SortedSet接口,它是一个有序的集合类,TreeSet的底层是通过TreeMap实现的。TreeSet并不是根据插入的顺序来排序,而是根据实际的值的大小来排序。TreeSet也支持两种排序方式:自然排序和自定义排序。不能放入重复元素和null。
4.ArrayList与LinkedList
ArrayList类
处理有顺序的单列数据
保存数据的存储空间,会自动扩展【注意与数组的区别】
可以保存任意数据类型的数据 【注意与数组的区别】
数据存储结构是动态数组结构【优势:查询速度快 缺点:添加/删除速度慢】
所属包:java.util
构造方法:
ArrayList() 构造一个初始容量为10的空列表。
ArrayList(Collection c) 将实现Collection接口的集合类转换成ArrayList
ArrayList(int initialCapacity) 构造具有指定初始容量的空列表。

例如:
package com.click369.test1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class TestMain {
	public static void main(String[] args) {
		//测试ArrayList的构造方法--创建对象
		//ArrayList() 构造一个初始容量为10的空列表。
		ArrayList  list1=new ArrayList();
		//ArrayList(Collection c) 将实现Collection接口的集合类转换成ArrayList
		ArrayList  list2=new ArrayList(list1);
		//ArrayList(int initialCapacity) 构造具有指定初始容量的空列表。
		ArrayList  list3=new ArrayList(30);
		//可以利用List接口
		List  list11=new ArrayList();
		List  list22=new ArrayList(list11);
		List  list33=new ArrayList(40);
		//可以利用Collection接口
		Collection  list111=new ArrayList();
		Collection  list222=new ArrayList(list111);
		Collection  list333=new ArrayList(50);
	}
}

实例方法
add(E e) 将指定的元素追加到此列表的末尾。
clear() 从列表中删除所有元素。
contains(Object o) 如果此列表包含指定的元素,则返回 true 。
get(int index) 返回此列表中指定位置的元素。
indexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1
lastIndexOf(Object o) 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。
isEmpty() 如果此列表不包含元素,则返回 true 。
remove(int index) 删除该列表中指定位置的元素。
remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)。
set(int index, E element) 用指定的元素替换此列表中指定位置的元素。
size() 返回此列表中的元素数。
toArray()以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组

例如:
package com.click369.test2;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class TestMain {

	public static void main(String[] args) {
		//ArrayList中的实例方法
		ArrayList list1=new ArrayList();
		//1.add(E e) 将指定的元素追加到此列表的末尾。
		list1.add("hello");
		list1.add(true);
		list1.add(12.5);
		list1.add("hello");
		//2.size() 返回此列表中的元素数。
		System.out.println("list1的元素数="+list1.size());
		//3.clear() 从列表中删除所有元素。[清空]
		//list1.clear();
		//System.out.println("list1的元素数="+list1.size());
		//4.contains(Object o) 如果此列表包含指定的元素,则返回 true 。
		System.out.println("判断hello元素是否在list1这个集合中=="+list1.contains("hello1"));
		//5.get(int index) 返回此列表中指定位置的元素。
		//System.out.println("get(5)=="+list1.get(5));
		//6.indexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1
		System.out.println("hello元素在list1中第一次出现的位置=="+list1.indexOf("hello"));
		//7.lastIndexOf(Object o) 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。
		System.out.println("hello元素在list1中最后一次出现的位置=="+list1.lastIndexOf("hello"));
		//8.isEmpty() 如果此列表不包含元素,则返回 true 。
		//list1.clear();
		//System.out.println("list1集合是否为空="+list1.isEmpty());
		//9.remove(int index) 删除该列表中指定位置的元素。 
		//list1.remove(2);
		//System.out.println("list1的元素数="+list1.size());
		//10.remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)。 
		//list1.remove("hello");
		//System.out.println("list1的元素数="+list1.size());
		//System.out.println("get(0)=="+list1.get(0));
		//11.set(int index, E element) 用指定的元素替换此列表中指定位置的元素。
		list1.set(0,"world");
		System.out.println("get(0)=="+list1.get(0));
		//12.toArray()以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的[Object]数组
		Object[] objs=list1.toArray();
	}
}

LinkedList类
处理有顺序的单列数据
保存数据的存储空间,会自动扩展【注意与数组的区别】
可以保存任意数据类型的数据 【注意与数组的区别】
数据存储结构是链表【火车】结构【优势:添加/删除速度快 缺点:查询速度慢】

构造方法:
LinkedList() 构造一个空列表。
LinkedList(Collection c) 将实现Collection接口的集合类转换成LinkedList

例如:
package com.click369.test1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
public class TestMain {
	public static void main(String[] args) {
		//测试LinkedList的构造方法--创建对象
		//LinkedList() 构造一个空列表。
		LinkedList  list1=new LinkedList();
		//LinkedList(Collection c) 将实现Collection接口的集合类转换成LinkedList
		ArrayList  alist=new ArrayList();
		LinkedList  list2=new LinkedList(alist);
		//可以利用List接口
		List  list11=new LinkedList();
		List  list22=new LinkedList(list11);
		//可以利用Collection接口
		Collection  list111=new LinkedList();
		Collection  list222=new LinkedList(list111);
	}
}

实例方法与ArrayList一样:
add(E e) 将指定的元素追加到此列表的末尾。
clear() 从列表中删除所有元素。
contains(Object o) 如果此列表包含指定的元素,则返回 true 。
get(int index) 返回此列表中指定位置的元素。
indexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1
lastIndexOf(Object o) 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。
isEmpty() 如果此列表不包含元素,则返回 true 。
remove(int index) 删除该列表中指定位置的元素。
remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)。
set(int index, E element) 用指定的元素替换此列表中指定位置的元素。
size() 返回此列表中的元素数。
toArray()以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组

LinkedList类提供了一组针对第一个元素和最后一个元素的操作方法:
addFirst(E e) 在该列表开头插入指定的元素。
addLast(E e) 将指定的元素追加到此列表的末尾
getFirst() 返回此列表中的第一个元素。
getLast() 返回此列表中的最后一个元素。
removeFirst() 从此列表中删除并返回第一个元素。
removeLast() 从此列表中删除并返回最后一个元素。
因为LinkedList类的数据存储结构是链表【火车】结构

例如:
package com.click369.test2;
import java.util.LinkedList;
public class TestMain {

	public static void main(String[] args) {
		//LinkedList中的实例方法
		LinkedList list1=new LinkedList();
		//1.add(E e) 将指定的元素追加到此列表的末尾。
		list1.add("hello");
		list1.add(true);
		list1.add(12.5);
		list1.add("hello");
		//2.size() 返回此列表中的元素数。
		//System.out.println("list1的元素数="+list1.size());
		//3.clear() 从列表中删除所有元素。[清空]
		//list1.clear();
		//System.out.println("list1的元素数="+list1.size());
		//4.contains(Object o) 如果此列表包含指定的元素,则返回 true 。
		//System.out.println("判断hello元素是否在list1这个集合中=="+list1.contains("hello"));
		//5.get(int index) 返回此列表中指定位置的元素。
		//System.out.println("get(2)=="+list1.get(2));
		//6.indexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1
		//System.out.println("hello元素在list1中第一次出现的位置=="+list1.indexOf("hello"));
		//7.lastIndexOf(Object o) 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。
		//System.out.println("hello元素在list1中最后一次出现的位置=="+list1.lastIndexOf("hello"));
		//8.isEmpty() 如果此列表不包含元素,则返回 true 。
		//list1.clear();
		//System.out.println("list1集合是否为空="+list1.isEmpty());
		//9.remove(int index) 删除该列表中指定位置的元素。 
		//list1.remove(2);
		//System.out.println("list1的元素数="+list1.size());
		//10.remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)。 
		//list1.remove("hello");
		//System.out.println("list1的元素数="+list1.size());
		//System.out.println("get(0)=="+list1.get(0));
		//11.set(int index, E element) 用指定的元素替换此列表中指定位置的元素。
		//list1.set(0,"world");
		//System.out.println("get(0)=="+list1.get(0));
		//12.toArray()以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的[Object]数组
		//Object[] objs=list1.toArray();
		
		//LinkedList类提供了一组针对第一个元素和最后一个元素的操作方法:
		//addFirst(E e) 在该列表开头插入指定的元素。
		//addLast(E e) 将指定的元素追加到此列表的末尾
		//getFirst() 返回此列表中的第一个元素。 
		//getLast() 返回此列表中的最后一个元素。
		//removeFirst() 从此列表中删除并返回第一个元素。
		//removeLast() 从此列表中删除并返回最后一个元素。
		//因为LinkedList类的数据存储结构是链表【火车】结构
	}
}

LinkedList集合的遍历


package com.click369.test3;
import java.util.Iterator;
import java.util.LinkedList;
public class TestMain {
	public static void main(String[] args) {
		//LinkedList集合的遍历
		LinkedList  list=new LinkedList();
		list.add("hello");
		list.add(1001);
		list.add("world");
		list.add(true);
		list.add(12.5);
		//1.通过普通的for循环遍历ArrayList集合
		for(int i=0;i<list.size();i++){
			System.out.println("list---"+list.get(i));
		}
		//2、使用增强的for循环
		for(Object obj:list){
			System.out.println("obj---"+obj);
		}
		//3.使用Iterator  iterator()迭代器
		Iterator it=list.iterator();
		while(it.hasNext()){
			Object obj=it.next();
			System.out.println("Iterator---"+obj);
		}
	}
}

5.HashSet与LinkedHashSet
HashSet类
处理的是没有顺序的单列数据【重复的元素算一个】
保存数据的存储空间,会自动扩展。
可以保存任意数据类型的数据。
构造方法:
HashSet() 构造一个新的空集合; 背景HashMap实例具有默认初始容量(16)和负载因子(0.75)。
HashSet(Collection c)将实现Collection 接口的集合类转换成HashSet
HashSet(int initialCapacity) 构造一个新的空集合; 背景HashMap实例具有指定的初始容量和默认负载因子(0.75)
HashSet(int initialCapacity, float loadFactor) 构造一个新的空集合; 背景HashMap实例具有指定的初始容量和指定的负载因子

例如:
package com.click369.test1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class TestMain {
	public static void main(String[] args) {
		//测试HashSet的构造方法--创建对象
		//HashSet() 构造一个新的空集合; 背景HashMap实例具有默认初始容量(16)和负载因子(0.75)。
		HashSet set1=new HashSet();
		//HashSet(Collection c)将实现Collection 接口的集合类转换成HashSet
		ArrayList list=new ArrayList();
		HashSet	set2=new HashSet(list);	
		//HashSet(int initialCapacity) 构造一个新的空集合; 背景HashMap实例具有指定的初始容量和默认负载因子(0.75)。 
		HashSet set3=new HashSet(10);
		//HashSet(int initialCapacity, float loadFactor) 构造一个新的空集合; 背景HashMap实例具有指定的初始容量和指定的负载因子
		HashSet set4=new HashSet(10,0.5f);
		//可以使用Set接口
		Set set11=new  HashSet();
		Set set22=new  HashSet(list);
		Set set33=new  HashSet(30);
		Set set44=new  HashSet(40,0.5f);
		//可以使用Collection接口
		Collection set111=new  HashSet();
		Collection set222=new  HashSet(list);
		Collection set333=new  HashSet(30);
		Collection set444=new  HashSet(40,0.5f);
	}
}

实例方法:
add(E e) 将指定的元素添加到此集合。
clear() 从此集合中删除所有元素。
contains(Object o) 如果此集合包含指定的元素,则返回 true 。
isEmpty() 如果此集合不包含元素,则返回 true 。
remove(Object o) 如果存在,则从该集合中删除指定的元素。
size() 返回此集合中的元素数。
toArray()以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的[Object]数组

例如:
package com.click369.test2;

import java.util.HashSet;

public class TestMain {

	public static void main(String[] args) {
		//HashSet中的实例方法
		HashSet set1=new HashSet();
		//1.add(E e) 将指定的元素追加到此列表的末尾。
		set1.add("hello");
		set1.add(true);
		set1.add(12.5);
		set1.add("hello");
		//2.size() 返回此列表中的元素数。
		//System.out.println("set1的元素数="+set1.size());
		//3.clear() 从列表中删除所有元素。[清空]
		//set1.clear();
		//System.out.println("set1的元素数="+set1.size());
		//4.contains(Object o) 如果此列表包含指定的元素,则返回 true 。
		System.out.println("判断hello元素是否在set1这个集合中=="+set1.contains("hello"));
		//5.isEmpty() 如果此列表不包含元素,则返回 true 。
		//set1.clear();
		//System.out.println("set1集合是否为空="+set1.isEmpty());
		//6.remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)。 
		set1.remove("hello");
		System.out.println("set1的元素数="+set1.size());
		//7.toArray()以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的[Object]数组
		Object[] objs=set1.toArray();
	}
}

HashSet集合的遍历

package com.click369.test3;
import java.util.HashSet;
import java.util.Iterator;
public class TestMain {
	public static void main(String[] args) {
		//HashSet集合的遍历
		HashSet  set=new HashSet();
		set.add("hello");
		set.add(1001);
		set.add("world");
		set.add(true);
		set.add(12.5);
		//1、使用增强的for循环
		for(Object obj:set){
			System.out.println("obj---"+obj);
		}
		//2.使用Iterator  iterator()迭代器
		Iterator it=set.iterator();
		while(it.hasNext()){
			Object obj=it.next();
			System.out.println("Iterator---"+obj);
		}
	}
}

LinkedHashSet类
定义结构:
public class LinkedHashSet
extends HashSet
implements Set,

LinkedHashSet是HashSet类的子类
只要会使用HashSet,那么就一定会使用LinkedHashSet。
构造方法:
LinkedHashSet() 构造一个新的空集合; 背景HashMap实例具有默认初始容量(16)和负载因子(0.75)。
LinkedHashSet(Collection c)将实现Collection 接口的集合类转换成LinkedHashSet
LinkedHashSet(int initialCapacity) 构造一个新的空集合; 背景HashMap实例具有指定的初始容量和默认负载因子(0.75)。
LinkedHashSet(int initialCapacity, float loadFactor) 构造一个新的空集合; 背景HashMap实例具有指定的初始容量和指定的
实例方法:
add(E e) 将指定的元素添加到此集合。
clear() 从此集合中删除所有元素。
contains(Object o) 如果此集合包含指定的元素,则返回 true 。
isEmpty() 如果此集合不包含元素,则返回 true 。
remove(Object o) 如果存在,则从该集合中删除指定的元素。
size() 返回此集合中的元素数。
iterator() 返回此集合中元素的迭代器。

6.HashMap与Hashtable与TreeMap与ConcurrentHashMap
HashMap类
可以处理键值对数据
保存键值对数据的存储空间会自动扩展。
所保存的键值对数据可以为null.[1.null=”sss” 2. “sss”=null 3. null=null]
保存的键值对数据是无序的。
不能有重复的键【重复的键算一个数据】
标题=页码 【键】=【值】
构造方法:
HashMap() 构造一个空的 HashMap ,默认初始容量(16)和默认负载系数(0.75)。
HashMap(int initialCapacity) 构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。
HashMap(int initialCapacity, float loadFactor) 构造一个空的 HashMap具有指定的初始容量和负载因子。
HashMap(Map m) 将实现Map接口的集合类转换成HashMap

例如:
package com.click369.test1;
import java.util.HashMap;
import java.util.Map;
public class TestMain {
	public static void main(String[] args) {
		//HashMap的构造方法--创建对象
		//HashMap() 构造一个空的 HashMap ,默认初始容量(16)和默认负载系数(0.75)。 
		HashMap  map1=new HashMap();
		//HashMap(int initialCapacity) 构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。
		HashMap map2=new HashMap(20);
		//HashMap(int initialCapacity, float loadFactor) 构造一个空的 HashMap具有指定的初始容量和负载因子。
		HashMap map3=new HashMap(30,0.5f);
		//HashMap(Map m) 将实现Map接口的集合类转换成HashMap
		HashMap map4=new HashMap(map1);
		//可以利用Map接口
		Map  map11=new HashMap();
		Map  map22=new HashMap(20);
		Map  map33=new HashMap(30,0.5f);
		Map  map44=new HashMap(map33);
	}
}

HashMap常用的实例方法:
put(K key, V value) 添加键值对数据。
size() 得到集合中键值对元素的个数。
isEmpty() 判断集合书否为空
clear() 清空集合。
containsKey(Object key) 判断指定的键数据在集合中是否存在。
containsValue(Object value) 判断指定的值数据在集合中是否存在 。
get(Object key)根据指定的键数据得到与这个键对应的值数据。
remove(Object key)根据指定的键数据删除整个键值对数据。
replace(K key, V oldValue, V newValue) 根据指定的键数据替换对应的值数据。

例如:
package com.click369.test2;
import java.util.HashMap;
import java.util.Map;
public class TestMain {
	public static void main(String[] args) {
		//HashMap的实例方法
		HashMap map1=new HashMap();
		//1.put(K key, V value) 添加键值对数据。 
		//键或者值都可以是任意数据类型
		map1.put("hello", 1001);
		map1.put(1002,"world");
		map1.put(true, 12.5);
		map1.put(120.5, false);
		//所保存的键值对数据可以为null.
		//map1.put(null, "test"); //键为null,值不为null
		//map1.put("test",null); //键不为null,值为null
		//map1.put(null,null); ///键为null,值为null
		//不能有重复的键【重复的键算一个数据】
		//map1.put("java","test1");
		//map1.put("java","test2");
		//2.size() 得到集合中键值对元素的个数。 
		System.out.println("map1集合键值对元素的个数=="+map1.size());
		//3.isEmpty() 判断集合是否为空 
		System.out.println("map1集合判断集合是否为空=="+map1.isEmpty());
		//4.clear() 清空集合。 
		//5.containsKey(Object key) 判断指定的键数据在集合中是否存在。
		System.out.println("判断指定的键数据在集合中是否存在=="+map1.containsKey("hello"));
		//6.containsValue(Object value) 判断指定的值数据在集合中是否存在 。
		System.out.println("判断指定的值数据在集合中是否存在=="+map1.containsValue("hello"));
		//7.get(Object key)根据指定的键数据得到与这个键对应的值数据。
		System.out.println("根据指定的键数据得到与这个键对应的值数据=="+map1.get("hello"));
		//8.remove(Object key)根据指定的键数据删除整个键值对数据。
		//map1.remove(true);
		//System.out.println("map1集合键值对元素的个数=="+map1.size());
		//System.out.println("根据指定的键数据得到与这个键对应的值数据=="+map1.get(true));
		//9.replace(K key, V oldValue, V newValue) 根据指定的键数据替换对应的值数据。
		System.out.println("根据指定的键数据得到与这个键对应的值数据=="+map1.get(1002));
		map1.replace(1002, "world", "hello");
		System.out.println("根据指定的键数据得到与这个键对应的值数据=="+map1.get(1002));
	}
}

遍历键值对对集合:
Set keySet() 得到键值对集合中所有键值对数据的键数据保存到set集合中
Collection values() 得到键值对集合中所有键值对数据的键数据保存到Collection集合中
Set<Map.Entry<K,V>> entrySet()得到键值对集合中所有键值对数据保存到Set<Map.Entry<K,V>>集合中.

例如:
public static void main(String[] args) { 
		HashMap  map=new	HashMap();
		map.put(100,"zhangsan");
		map.put(12.5,true);
		map.put("test",1000);
		map.put(false,168.5);
		//Set<K>  keySet() 得到键值对集合中所有键值对数据的键数据保存到set集合中
		Set  keyset=map.keySet();
		for(Object  objkey:keyset){
			System.out.println("key==="+objkey);
		}	

		//Collection<V> values() 得到键值对集合中所有键值对数据的键数据保存到Collection<V>集合中
		Collection  vals=map.values();
		for(Object  objvalue:vals){
			System.out.println("value==="+objvalue);
		}	

		//Set<Map.Entry<K,V>>  entrySet()得到键值对集合中所有键值对数据保存到Set<Map.Entry<K,V>>集合中
		Set   k_v_set=map.entrySet();
		for(Object obj:k_v_set){
			System.out.println(obj);
		}
	
		//遍历Map集合的方法
		HashMap<String,String>  testmap=new	HashMap<String,String>();
		testmap.put("name","zhangsan");
		testmap.put("pass","123456");
		testmap.put("address","西安");
		for(Map.Entry<String,String>  entry:testmap.entrySet()){
			//System.out.println("mykey=="+entry.getKey());
			//System.out.println("myvalue=="+entry.getValue());
			System.out.println("k-v=="+entry.getKey()+":"+entry.getValue());
		}
	}

Hashtable类
可以处理键值对数据
保存键值对数据的存储空间会自动扩展。
不允许null出现
不能有重复的键【重复的键算一个数据】
保存的键值对数据是无序的。
构造方法:
Hashtable() 构造一个空的 Hashtable,默认初始容量(11)和默认负载系数(0.75)。
Hashtable(int initialCapacity) 构造一个空的 Hashtable具有指定的初始容量和默认负载因子(0.75)。
Hashtable(int initialCapacity, float loadFactor) 构造一个空的 Hashtable具有指定的初始容量和负载因子。
Hashtable(Map m) 将实现Map接口的集合类转换成Hashtable

例如:
package com.click369.test1;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
public class TestMain {
	public static void main(String[] args) {
		//Hashtable的构造方法--创建对象
		//Hashtable() 构造一个空的 Hashtable ,默认初始容量(11)和默认负载系数(0.75)。 
		Hashtable  table1=new Hashtable();
		//Hashtable(int initialCapacity) 构造一个空的 Hashtable具有指定的初始容量和默认负载因子(0.75)。
		Hashtable table2=new Hashtable(20);
		//Hashtable(int initialCapacity, float loadFactor) 构造一个空的 Hashtable具有指定的初始容量和负载因子。
		Hashtable table3=new Hashtable(30,0.5f);
		//Hashtable(Map m) 将实现Map接口的集合类转换成Hashtable
		HashMap map4=new HashMap();
		Hashtable table4=new Hashtable(map4);
		//可以利用Map接口
		Map  table11=new Hashtable();
		Map  table22=new Hashtable(20);
		Map  table33=new Hashtable(30,0.5f);
		Map  table44=new Hashtable(table33);
	}
}

实例方法:
put(K key, V value) 添加键值对数据。
size() 得到集合中键值对元素的个数。
isEmpty() 判断集合书否为空
clear() 清空集合。
containsKey(Object key) 判断指定的键数据在集合中是否存在。
containsValue(Object value) 判断指定的值数据在集合中是否存在 。
get(Object key)根据指定的键数据得到与这个键对应的值数据。
remove(Object key)根据指定的键数据删除整个键值对数据。
replace(K key, V oldValue, V newValue) 根据指定的键数据替换对应的值数据。

例如:
package com.click369.test2;
import java.util.Hashtable;
public class TestMain {
	public static void main(String[] args) {
		//Hashtable的实例方法
		Hashtable table1=new Hashtable();
		//1.put(K key, V value) 添加键值对数据。 
		//键或者值都可以是任意数据类型
		table1.put("hello", 1001);
		table1.put(1002,"world");
		table1.put(true, 12.5);
		table1.put(120.5, false);
		//不允许null出现
		//table1.put(null, "test"); 
		//table1.put("test",null); 
		//不能有重复的键【重复的键算一个数据】
		//table1.put("java","test1");
		//table1.put("java","test2");
		//2.size() 得到集合中键值对元素的个数。 
		System.out.println("table1集合键值对元素的个数=="+table1.size());
		//3.isEmpty() 判断集合是否为空 
		System.out.println("table1集合判断集合是否为空=="+table1.isEmpty());
		//4.clear() 清空集合。 
		//5.containsKey(Object key) 判断指定的键数据在集合中是否存在。
		System.out.println("判断指定的键数据在集合中是否存在=="+table1.containsKey("hello"));
		//6.containsValue(Object value) 判断指定的值数据在集合中是否存在 。
		System.out.println("判断指定的值数据在集合中是否存在=="+table1.containsValue("hello"));
		//7.get(Object key)根据指定的键数据得到与这个键对应的值数据。
		System.out.println("根据指定的键数据得到与这个键对应的值数据=="+table1.get("hello"));
		//8.remove(Object key)根据指定的键数据删除整个键值对数据。
		table1.remove(true);
		System.out.println("table1集合键值对元素的个数=="+table1.size());
		System.out.println("根据指定的键数据得到与这个键对应的值数据=="+table1.get(true));
		//9.replace(K key, V oldValue, V newValue) 根据指定的键数据替换对应的值数据。
		System.out.println("根据指定的键数据得到与这个键对应的值数据=="+table1.get(1002));
		table1.replace(1002, "world", "hello");
		System.out.println("根据指定的键数据得到与这个键对应的值数据=="+table1.get(1002));
	}
}

遍历兼职对集合:
Set keySet() 得到键值对集合中所有键值对数据的键数据保存到set集合中
Collection values() 得到键值对集合中所有键值对数据的键数据保存到Collection集合中
Set<Map.Entry<K,V>> entrySet()得到键值对集合中所有键值对数据保存到Set<Map.Entry<K,V>>集合中.

例如:
package com.click369.test3;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class TestMain {
	public static void main(String[] args) {
		//Hashtable的遍历
		Hashtable<Object,Object> table1=new Hashtable<Object,Object>();
		table1.put("hello", 1001);
		table1.put(1002,"world");
		table1.put(true, 12.5);
		table1.put(120.5, false);
		//遍历所有的键数据
		//Set<K>  keySet() 得到键值对集合中所有键值对数据的键数据保存到set集合中
		Set set1=table1.keySet();
		for(Object obj:set1){
			System.out.println("key=="+obj);
		}
		//使用迭代器遍历键数据对饮的set集合
		Iterator keyit=set1.iterator();
		while(keyit.hasNext()){
			System.out.println("keyit=="+keyit.next());
		}
		
		//遍历所有的值数据
		//Collection<V> values() 得到键值对集合中所有键值对数据的键数据保存到Collection<V>集合中
		Collection coll=table1.values();
		for(Object val:coll){
			System.out.println("value=="+val);
		}
		//使用迭代器遍历键数据对饮的set集合
		Iterator valit=coll.iterator();
		while(valit.hasNext()){
					System.out.println("valit=="+valit.next());
				}
		
		//遍历所有的键和值数据
		//Set<Map.Entry<K,V>> entrySet()得到键值对集合中所有键值对数据保存到Set<Map.Entry<K,V>>集合中
		//注意:HashMap<Object,Object> map1=new HashMap<Object,Object>();
		for(Map.Entry<Object,Object> entry : table1.entrySet()){
			Object k=entry.getKey();
			Object v=entry.getValue();
			System.out.println(k+"="+v);
		}
	}
}

在这里插入图片描述
TreeMap的基本概念:

TreeMap集合是基于红黑树(Red-Black tree)的 NavigableMap实现。该集合最重要的特点就是可排序,该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。这句话是什么意思呢?就是说TreeMap可以对添加进来的元素进行排序,可以按照默认的排序方式,也可以自己指定排序方式。

根据上一条,我们要想使用TreeMap存储并排序我们自定义的类(如User类),那么必须自己定义比较机制:一种方式是User类去实现java.lang.Comparable接口,并实现其compareTo()方法。另一种方式是写一个类(如MyCompatator)去实现java.util.Comparator接口,并实现compare()方法,然后将MyCompatator类实例对象作为TreeMap的构造方法参数进行传参(当然也可以使用匿名内部类),这些比较方法是怎么被调用的将在源码中讲解。

下图是Map集合体系类图。
在这里插入图片描述
类名及类成员变量:

public class TreeMap<K,V>
    extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable
{
    // 比较器对象
    private final Comparator<? super K> comparator;
 
    // 根节点
    private transient Entry<K,V> root;
 
    // 集合大小
    private transient int size = 0;
 
    // 树结构被修改的次数
    private transient int modCount = 0;
 
    // 静态内部类用来表示节点类型
    static final class Entry<K,V> implements Map.Entry<K,V> {
        K key;     // 键
        V value;   // 值
        Entry<K,V> left;    // 指向左子树的引用(指针)
        Entry<K,V> right;   // 指向右子树的引用(指针)
        Entry<K,V> parent;  // 指向父节点的引用(指针)
        boolean color = BLACK; // 
    }
}

类构造方法:

 public TreeMap() {   // 1,无参构造方法
        comparator = null; // 默认比较机制
    }
 
    public TreeMap(Comparator<? super K> comparator) { // 2,自定义比较器的构造方法
        this.comparator = comparator;
    }
 
    public TreeMap(Map<? extends K, ? extends V> m) {  // 3,构造已知Map对象为TreeMap
        comparator = null; // 默认比较机制
        putAll(m);
    }
 
    public TreeMap(SortedMap<K, ? extends V> m) { // 4,构造已知的SortedMap对象为TreeMap
        comparator = m.comparator(); // 使用已知对象的构造器
        try {
            buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
        } catch (java.io.IOException cannotHappen) {
        } catch (ClassNotFoundException cannotHappen) {
        }
}

ConcurrentHashMap:
采用了非常精妙的"分段锁"策略,ConcurrentHashMap的主干是个Segment数组。Segment继承了ReentrantLock,所以它就是一种可重入锁(ReentrantLock)。在ConcurrentHashMap,一个Segment就是一个子哈希表,Segment里维护了一个HashEntry数组,并发环境下,对于不同Segment的数据进行操作是不用考虑锁竞争的。
7.Conllection与Conllections
Collections类 【集合操作类的辅助类】
提供对集合进行操作的查询,复制,排序,线程安全操作的一系列静态方法
集合操作类的辅助类,与数组的辅助类【Arrays】相似。

例如:
package com.click369.test1;

import java.util.ArrayList;
import java.util.Collections;

public class TestMain {

	public static void main(String[] args) {
		//Collections类
		//是集合操作类的辅助类
		//提供了一组操作集合的静态方法【查询集合元素,复制集合中的元素进入另一个集合,为集合中的元素排序...】
		ArrayList list1=new ArrayList();
		list1.add("zhangsan");
		list1.add("lisi");
		list1.add("Lisi");
		list1.add("zhaoliu");
		//static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) 返回给定集合的最大元素。  
		Object  max=Collections.max(list1);
		System.out.println(max);
		//static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) 返回给定集合的最小元素。  
		Object  min=Collections.min(list1);
		System.out.println(min);
		System.out.println("------------------------");
		System.out.println("没有排序之前");
		for(Object obj:list1){
			System.out.println("没有排序之前=="+obj);
		}
		System.out.println("------------------------");
		// sort(List<T> list) 对指定的列表进行排序。
		Collections.sort(list1);
		System.out.println("排序之后");
		for(Object obj:list1){
			System.out.println("排序之后=="+obj);
		}
		//static <T> void copy(List<? super T> dest, List<? extends T> src) 将所有元素从一个列表复制到另一个列表中,会覆盖目标列表中的对应数据元素。  
		//注意:目标集合的元素个数  >= 源集合的元素个数 ,否则java.lang.IndexOutOfBoundsException: Source does not fit in dest
		ArrayList list2=new ArrayList();
		list2.add(234);
		list2.add(547);
		list2.add(13);
		list2.add(464);
		list2.add(4565);
		list2.add(6579823);
		Collections.copy(list2, list1);
		for(Object obj:list2){
			System.out.println("list2=="+obj);
		}
	}
}

Collection是集合类的上级接口,继承与他有关的接口主要有List和Set
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全等操作

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值