引用
一. 总的框架
总的有Collection和Map
Collection包含:Set(无序,不可以重复),Queue和List(有序,可以重复)
Set包含:EnumSet,SortedSet,HashSet
SortedSet包含:TreeSet
HashSet包含:LinkedHashSet
Queue包含:Deque,PriorityQueue
Deque包含LinkedList
List包含:ArrayList,Vector,LinkedList
Vector包含:Stack
Map包含:EnumMap,IdentityHashMap,HashMap,HashTable,SortedMap,WeakHashMap
HashMap包含:LinkedHashMap
HashTable包含:Properties
SortedMap包含:TreeMap
HashMap和Hashtable的区别
1.HashMap是线程不安全的,如果有需要,可以用Collections中的静态类转换
Hashtable是线程安全的
返回指定 collection 支持的同步(线程安全的)collection。为了保证按顺序访问,必须通过返回的 collection 完成所有对底层实现 collection 的访问。
在返回的 collection 上进行迭代时,用户必须手工在返回的 collection 上进行同步:
Collection c = Collections.synchronizedCollection(myCollection);
...
synchronized(c) {
Iterator i = c.iterator(); // Must be in the synchronized block
while (i.hasNext())
foo(i.next());
}
2.HashMap可以为null(key和value都可以)
Hashtable不可以为null(key和value都不可以)
3.HashMap继承自Map类
Hashtable继承自Dictionary类
4.Hashtable是用Enumeration进行遍历的:public Enumeration<K> keys()
Hashtable hash=new Hashtable();
hash.put( "abc","1");
hash.put("ddd","1");
hash.put( "asdf","2");
Enumeration enumkey = hash.keys() ;
while(enumkey.hasMoreElements()){
String str=(String)enumkey.nextElement();
System.out.println("--------"+str);
System.out.println("========="+hash.get( str));//获得值value
if("1".equals(hash.get( str)))
hash.remove( str);
}
HashMap和HashSet的区别
1.HashMap实现了Map接口
HashSet实现了set接口
2.HashMap存键值对
HashSet存对象
3.HashMap是用put加入
HashSet是用add加入
4.HashMap是使用键对象的hashcode
HashSet是使用成员对象计算hashcode值,可以用equals来判断对象的相等性
5.HashMap比较快,因为使用唯一的键来获取对象
HashSet相对比较慢
二:Collection各个类总结与代码
1. Collection
集合必须只有对象,集合中的元素不能是基本数据类型
1.1 方法:
boolean add(Object element)
boolean remove(Object element)
int size()
boolean isEmpty()
boolean contains(Object element)
Iterator iterator()
1.2迭代器:
含有三个方法:
next():获取下一个对象
hasNext():判断是否有下一个对象
remove():移除对象
2. List
2.1特点:
List最大的特点就是能够自动的根据插入的数据量来动态地改变容器的大小
该接口不但能够对列表的一部分进行操作,还添加了面向位置的操作
List是按对象的进入顺序进行保存对象,而不做排序或编辑操作
2.2方法:
Void add(int index,Object element):添加对象element到位置index上
Boolean addAll(int index,Collection collection):在index位置后添加容器collection中所有的元素
Object get(int index):取出下标为index的位置的元素
Int indexOf(Object element):查找对象element在List中第一次出现的位置
Int lastIndexOf(Object element):查找对象element在List中最后出现的位置
Object remove(intindex):删除index位置上的元素
Object set(int index,Object element):将index位置上的对象替换为element并返回老的元素。
ListIterator listIterator():返回一个ListIterator迭代器,默认开始位置为0;
ListIterator listIterator(int startIndex):返回一个ListIterator迭代器,默认开始位置为startIndex;
List subList(int fromIndex,int toIndex):返回一个子列表List,元素存放为从fromIndex(含)到toIndex(不含)之前的元素
三:Map各个类总结与代码
3.1特点:
该接口描述了从不重复的键到值的映射
改变操作允许从映射中添加和除去键-值对。键和值都可以为null。但是,不能把Map作为一个键或值添加给自身。
这个方法分为三组操作:改变,查询和提供可选视图
3.2方法:
改变
Object put(Object key,Object value):用来存放一个键-值对Map中
Object remove(Object key):根据key,移除一个键-值对,并将值返回
Void putAll(Map mapping):将另外一个Map中的元素存入到当前的Map中
Void clear():清空当前Map中的元素
查询
Object get(Object key):根据key(键)取得对应的值
Boolean containsKey(Object key):判断Map中是否存在某键(Key)
Boolean containsKey(Object value)判断Map中是否存在某值(value)
Int size()返回Map中键-值对的个数
Boolean isEmpty():判断当前Map是否为空
允许把键或值的组作为集合来处理
Public Set keyset():返回所有的键(key),并使用Set容器存放
Public Collection values():返回所有的值(value),并使用Collection存放
Public Set entrySet():返回一个实现Map.Entry接口的元素Set
3.3 LinkedHashMap和TreeMap的特点与使用
HashMap的存入顺序和输出顺序无关。而LinkedHashMap则保留了键值对的存入顺序。TreeMap则是对Map中的元素进行排序。使用HashMap或者LinkedHashMap来存放元素,当所有的元素都存放完之后,如果需要一个经过排序的Map的话,再使用TreeMap来重构原来Map对象。因为HashMap和LinkedHashMap存储数据的速度比直接使用TreeMao要快,存取效率要高。当完成了所有的元素的存放之后,再对整个的Map中的元素进行排序,这样可以提高整个程序的运行效率,缩短执行时间。这里是使用键(Key)进行排序的。而如果使用TreeMap来进行正常排序的话,Key中存放的对象必须实现Comparable接口
3.4Comparable接口
JDK中只有十四个类实现了此接口
按数字大小排序:BigDecimal,BigInteger,Byte,Double,Float,Integer,Long,Short
按Unicode值的数字大小排序:Character
按语言环境敏感的字符串排序:CollationKey
按年代排序:Date
按系统特定的路径名的权限定字符的Unicode值排序:File
按名字中字符的Unicode值排序:ObjectStreamField
按字符串中字符Unicode值排序:String
3.5HashMap的进一步理解
因为HashMap中使用Hash算法,所以需要先了解一下Hash算法和Hash表
Hash算法的意义在于提供了一种快速存取数据的方法,它用一种算法建立键值与真实值之间的对应关系(每一个真实值只能有一个键值,但是每一个键值可以对应多个真实值),这样可以快速在数组等里面存取数据。
我们建立一个HashTable(哈希表),该表长度为N,然后我们分别在该表中的格子中存放不同的元素。每个格子下面存放的元素又是以链表的方式存放元素。
A. 当添加一个新的元素Entry的时候,首先我们通过一个Hash函数计算出这个Entry元素的Hash值hashcode。通过该hashcode值就可以直接定位出我们应该把这个Entry元素存入到Hash表的哪个格子中,如果该格子中已经存在元素了,那么只要把新的Entry元素放到这个链表中即可。
B. 如果要查找一个元素Entry的时候,也同样的方式,通过hash 函数计算出这个Entry元素的Hash值hashcode。然后通过该hashcode值,就可以直接找到这个Entry是存放到哪个格子中的。接下来就对这个格子存放的链表元素进行逐个的比较查找就可以了。
重构Hash表的方法:void resize(int newCapacity)是如何实现的
A. 首先判断如果Hash表的长度已经达到最大值,那么就不进行重构了。
B. 然后就是构建新的Hash表
C. 把老的Hash表中的对象数据全部转移到新的Hash表newTable中,并设置新的重构因子threshold
HashCode的计算,是用来定位我们的键值对应该放到Hash表中哪个格子的关键属性,而这个HashCode的计算方法是调用的各个对象自己实现的hashCode()方法。而这个方法是在Object对象中定义的,所以自己定义的类如果需要再集合中使用的话,就需要正确的重写hashcode()方法。
总结Java标准类库的容器类:
1。数组把对象和数字形式的下标联系起来。它持有的是类型确定的对象,这样提取对象的时候就不用再作类型传递了。它可以是多维的,也可以持有primitive。但是创建之后它的容量不能改了。
2。Collection持有单个元素,而Map持有相关联的pair。
3。和数组一样,List也把数字下标同对象联系起来,你可以把数组和List想成有序的容器。List会随元素的增加自动调整容量。但是List只能持有Object reference,所以不能存放primitive,而且把Object提取出来之后,还要做类型传递。
4。如果要做很多随机访问,那么请用ArrayList,但是如果要再List的中间做很多插入和删除的话,就应该用LinkedList了。
5。LinkedList能提供队列,双向队列和栈的功能。
6。Map提供的不是对象与数组的关联,而是对象和对象的关联。
HashMap看重的是访问速度,而TreeMap各国那看重键的顺序,因而它不如HashMap那么快。而LinkedHashMap则保持对象插入的顺序,但是也可以用LRU算法为它重新排序。
7。Set只接受不重复的对象。HashSet提供了最快的查询速度。而TreeSet则保持元素有序。LinkedHashSet保持元素的插入顺序。
8。没必要再在新代码里使用旧类库留下来的Vector,Hashtable和Stack了。
package com.collection.sym;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import com.sun.org.apache.bcel.internal.generic.NEW;
public class TestCollection {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Collection collection1=new LinkedList();
collection1.add("122121");
collection1.add("gegege");
System.out.println("集合collection1的大小:"+collection1.size());//2
System.out.println("集合collection1的内容:"+collection1);//[122121, gegege]
System.out.println("集合collection1的内容:"+collection1.contains("122121"));//true
Collection collection2=new ArrayList();
collection2.addAll(collection1);
System.out.println("集合collection2的内容:"+collection1);//[122121, gegege]
//集合转化为数组
Object[]str=collection1.toArray();
for (int i = 0; i < str.length; i++) {
System.out.println(str[i]);
}
//Iterator的使用方式
for (Iterator i = collection1.iterator(); i.hasNext(); ) {
System.out.println(i.next());
i.remove();
}
System.out.println("集合collection1的大小:"+collection1.size());//表明移除了
List list3=new ArrayList();
list3.addAll(collection2);
list3.add("67463");
//list3的元素有:122121 gegege 67463
System.out.println("集合list3的大小:"+list3.size());//3
for (ListIterator listIterator=list3.listIterator(2);listIterator.hasPrevious();) {
System.out.println(listIterator.previous());
}
//打印结果:gegege 122121
System.out.println(list3.get(1));//gegege
Map map=new HashMap();
map.put(1, "jin");
map.put(2, "kun");
map.put(3, "unn");
System.out.println("entrySet:"+map.entrySet());//entrySet:[1=jin, 2=kun, 3=unn]
Set set=map.keySet();
System.out.println("set:"+map.keySet());//set:[1, 2, 3]
HashMap map1=new HashMap();
Map map2=new LinkedHashMap();
for (int i = 0; i < 10; i++) {
double s=Math.random()*100;
map1.put(new Integer((int)s), "第"+i+"个元素"+s+"\n");
map2.put(new Integer((int)s), "第"+i+"个元素"+s+"\n");
}
System.out.print("map1未排序前HashMap:"+map1);
System.out.print("map2未排序前LinkedHashMap:"+map2);
System.out.print("map1排序后HashMap:"+new TreeMap(map1));
System.out.print("map2排序后LinkedHashMap:"+new TreeMap(map2));
}
}
/* map1未排序前HashMap:{84=第0个元素84.35521380903046
, 48=第8个元素48.96178930057452
, 64=第9个元素64.36866045893255
, 38=第7个元素38.30435615532761
, 23=第2个元素23.40733604154718
, 59=第3个元素59.53478003506187
, 77=第6个元素77.78947006016652
, 92=第4个元素92.07739619260532
, 58=第1个元素58.22163014592003
, 63=第5个元素63.300719312567196
}map2未排序前LinkedHashMap:{84=第0个元素84.35521380903046
, 58=第1个元素58.22163014592003
, 23=第2个元素23.40733604154718
, 59=第3个元素59.53478003506187
, 92=第4个元素92.07739619260532
, 63=第5个元素63.300719312567196
, 77=第6个元素77.78947006016652
, 38=第7个元素38.30435615532761
, 48=第8个元素48.96178930057452
, 64=第9个元素64.36866045893255
}map1排序后HashMap:{23=第2个元素23.40733604154718
, 38=第7个元素38.30435615532761
, 48=第8个元素48.96178930057452
, 58=第1个元素58.22163014592003
, 59=第3个元素59.53478003506187
, 63=第5个元素63.300719312567196
, 64=第9个元素64.36866045893255
, 77=第6个元素77.78947006016652
, 84=第0个元素84.35521380903046
, 92=第4个元素92.07739619260532
}map2排序后LinkedHashMap:{23=第2个元素23.40733604154718
, 38=第7个元素38.30435615532761
, 48=第8个元素48.96178930057452
, 58=第1个元素58.22163014592003
, 59=第3个元素59.53478003506187
, 63=第5个元素63.300719312567196
, 64=第9个元素64.36866045893255
, 77=第6个元素77.78947006016652
, 84=第0个元素84.35521380903046
, 92=第4个元素92.07739619260532
}*/