1、Collection 层次结构中的根接口
子接口set 元素无须 不可重复的集合(类似高中的集合)
HashSet LinkedHashSet TreeSet
子接口List 元素有序 可重复的集合(动态数组)
ArrayList Linkedlist Vector
2、Map接口 具有映射关系的key-value对的集合 y=f(x) (x1,y1)
HashMap
TreeMap
Hashtable
--------------------------------------------------------------------------------------------------------------------------------------------------------------
ArrayLit :有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问 元素,并搜索列表中的元素。
增add(5) 将指定的元素追加到此列表的尾部。
删remove(3) public E remove(int index)移除此列表中指定位置上的元素。向左移动所有后续元素(将其索引减 1)。
改set(3,new Integer("asad")) 用指定的元素替代此列表中指定位置上的元素。
查get(3) public E get(int index)返回此列表中指定位置上的元素。
插入 add(3,5) public void add(int index,E element)将指定的元素插入此列表中的指定位置。向右移动当前位于该位置的元素(如果有)以及所有后续元素(将其索引加 1)。
长度size() public int size()返回此列表中的元素数。
list.indexOf("as") 搜索给定参数第一次出现的位置
lastIndexOf 返回指定的对象在列表中最后一次出现的位置索引。
public Object[] toArray() 返回一个按照正确的顺序包含此列表中所有元素的数组。
public void clear()移除此列表中的所有元素。此调用返回后,列表将为空。
除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collections类的静态方法synchronizedMap获得线程安全的HashMap。
Map map = Collections.synchronizedMap(new HashMap());
在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可
以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。
它之所以有相当快的查询速度主要是因为它是通过计算散列码来决定存储的位置。
HashMap中主要是通过key的hashCode(hashCode是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值)来计算hash值的,只要hashCode相同,计算出来的hash值就一样。如果存储的对象对多了,就有可能不同的对象所算出来的hash值是相同的,这就出现了所谓的hash冲突。学过数据结构的同学都知道,解决hash冲突的方法有很多,HashMap底层是通过链表来解决hash冲突的。
当我们往HashMap中put元素的时候,先根据key的hashCode重新计算hash值,根据hash值得到这个元素在数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置
上。
HashMap其实就是一个Entry数组,Entry对象中包含了键和值,其中next也是一个Entry对象,它就是用来处理hash冲突的,形成一个链表。
loadFactor加载因子是表示Hsah表中元素的填满的程度,
必须在 "冲突的机会"与"空间利用率"之间寻找一种平衡与折衷. 这种平衡与折衷本质上是数据结构中有名的"时-空"矛盾的平衡与折衷.
如果机器内存足够,并且想要提高查询速度的话可以将加载因子设置小一点;相反如果机器内存紧张,并且对查询速度没有什么要求的话可以将加载因子设置大一点。不过一般我们都不用去设置它,让它取默认值0.75就好了。
// 若“key为null”,则将该键值对添加到table[0]中。 HashMap中则通过h&(length-1)的方法来代替取模,同样实现了均匀的散列,但效率要高很多,这也是HashMap对Hashtable的一个改进。
length为2的n次方,为偶数,length-1为奇数,最后一位为1,(h为hash值) length取2的整数次幂,是为了使不同hash值发生碰撞的概率较小,这样就能使元素在哈希表中均匀地散列。 如果这两个 Entry 的 key 通过 equals 比较返回 true,新添加 Entry 的 value 将覆盖集合中原有 Entry 的 value,但key不会覆盖。如果这两个 Entry 的 key 通过 equals 比较返回 false,新添加的 Entry 将与集合中原有 Entry 形成 Entry 链,而且新添加的 Entry 位于 Entry 链的头部 当HashMap中的元素越来越多的时候,hash冲突的几率也就越来越高,因为数组的长度是固定的。所以为了提高查询的效率,就要对HashMap的数组进行扩容,数组扩容这个操作也会出现在ArrayList中,这是一个常用的操作,而在HashMap数组扩容之后,最消耗性能的点就出现了:原数组中的数据必须重新计算其在新数组中的位置,并放进去,这就是resize。 扩容是需要进行数组复制的,复制数组是非常耗性能的操作,所以如果我们已经预知HashMap中元素的个数,那么预设元素的个数能够有效的提高HashMap的性能 HashMap和Hashtable的区别 HashMap不是线程安全的,HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
LinkedList底层的数据结构是基于双向循环链表的,且头结点中不存放数据,如下:
LinkedList<String> list = new LinkedList<String>(); 2 list.add("First"); 3 list.add("Second"); 4 list.add("Thrid"); 5 System.out.println(list); 6 ListIterator<String> itr = list.listIterator(); 7 while (itr.hasNext()) { 8 System.out.println(itr.next()); 9 }
有序否 | 允许元素重复否 | ||
Collection | 否 | 是 | |
List | 是 | 是 | |
Set | AbstractSet | 否 | 否 |
HashSet | |||
TreeSet | 是(用二叉树排序) | ||
Map | AbstractMap | 否 | 使用key-value来映射和存储数据,Key必须惟一,value可以重复 |
HashMap | |||
TreeMap | 是(用二叉树排序) |
java 遍历map的方法
package com.jackey.topic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
//循环遍历map的方法
public class CircleMap {
public static void main(String[] args) {
Map<String, Integer> tempMap = new HashMap<String, Integer>();
tempMap.put("a", 1);
tempMap.put("b", 2);
tempMap.put("c", 3);
// JDK1.4中
// 遍历方法一 hashmap entrySet() 遍历
System.out.println("方法一");
Iterator it = tempMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Object key = entry.getKey();
Object value = entry.getValue();
System.out.println("key=" + key + " value=" + value);
}
System.out.println("");
// JDK1.5中,应用新特性For-Each循环
// 遍历方法二
System.out.println("方法二");
for (Map.Entry<String, Integer> entry : tempMap.entrySet()) {
String key = entry.getKey().toString();
String value = entry.getValue().toString();
System.out.println("key=" + key + " value=" + value);
}
System.out.println("");
// 遍历方法三 hashmap keySet() 遍历
System.out.println("方法三");
for (Iterator i = tempMap.keySet().iterator(); i.hasNext();) {
Object obj = i.next();
System.out.println(obj);// 循环输出key
System.out.println("key=" + obj + " value=" + tempMap.get(obj));
}
for (Iterator i = tempMap.values().iterator(); i.hasNext();) {
Object obj = i.next();
System.out.println(obj);// 循环输出value
}
System.out.println("");
// 遍历方法四 treemap keySet()遍历
System.out.println("方法四");
for (Object o : tempMap.keySet()) {
System.out.println("key=" + o + " value=" + tempMap.get(o));
}
System.out.println("11111");
// java如何遍历Map <String, ArrayList> map = new HashMap <String,
// ArrayList>();
System.out.println("java 遍历Map <String, ArrayList> map = new HashMap <String, ArrayList>();");
Map<String, ArrayList> map = new HashMap<String, ArrayList>();
Set<String> keys = map.keySet();
Iterator<String> iterator = keys.iterator();
while (iterator.hasNext()) {
String key = iterator.next();
ArrayList arrayList = map.get(key);
for (Object o : arrayList) {
System.out.println(o + "遍历过程");
}
}
System.out.println("2222");
Map<String, List> mapList = new HashMap<String, List>();
for (Map.Entry entry : mapList.entrySet()) {
String key = entry.getKey().toString();
List<String> values = (List) entry.getValue();
for (String value : values) {
System.out.println(key + " --> " + value);
}
}
}
}