集合分为单例集合与双列集合
双列集合的5种遍历方式
import java.util.*;
public class day0 {
public static void main(String[] args) {
HashMap sm =new HashMap();
sm.put("abc","zhoguo");
sm.put("123","meiguo");
sm.put("555","yingguo");
//1.通过key获取
Set set = sm.keySet();
//自动迭代 item:迭代变量
for (String item : set) {
System.out.println(item+"\t"+sm.get(item));
}
//2.通过value获取
Collection values = sm.values();
for (String value : values) {
System.out.println(value);
}
//3.key与value同时获取
Set> entrySet = sm.entrySet();
for (Map.Entry entry : entrySet) {
System.out.println(entry.getKey()+"\t"+entry.getValue());
}
//俩种while
Iterator iterator = sm.keySet().iterator();
while (iterator.hasNext()){
String key = iterator.next();
System.out.println(key+"\t"+sm.get(key));
}
Iterator> iterator1 = sm.entrySet().iterator();
while (iterator1.hasNext()){
Map.Entry entry = iterator1.next();
System.out.println(entry.getKey()+"\t"+entry.getValue());
}
}
}
java的集合框架中,Collection接口是所有集合的根,然后扩展成三大类集合:
List:也就是有序集合,提供了方便的访问,插入,删除等操作
Set:set是不允许出现重复元素的
Queue/Deque:除了集合的基本功能外,还支持类似先入先出,或者后入先出等特定行为。通常是并发编程场合,再并发包中放着
单列集合自动扩容
所有语言中底层都是通过数组相互拷贝实现的
Vector:扩张成原来的2倍
ArrayList:扩容成原来的1.5倍
在实例化List的时候,jdk1.8中,默认的容量是0,在1.7与1.6中默认的是10,当通过add方法填入第一个元素时,元素为10
迭代器
迭代器是Iterator接口,有三个核心方法,维护指针可以向下移动next(),移动到指定位置后,取出当前位置的元素(next),以及重置指针操作remove
为什么数组和集合可以使用for循环进行迭代遍历?
所有的数组和集合都实现了Iterable接口,该接口中只有一个方法,iterator方法,返回值类型是Iterable类型,在iterable中有三个方法,hasNest,next,和remove,最主要的是hasNext和next,在底层帮我们去维护可以被迭代数组或集合的迭代
Map集合底层的数据结构
List单列结构:底层是数组实现的
set和map底层是通过数组和链表实现的
hashset是以hashmap为基础实现的
hashset保证元素的位于性,底层是通过hashCodde和equals结合实现的,在对比的过程中,先对比hashcode是否相同,然后对吧equals。
俩个对象是同一对象,hashcode一定相同,如果俩个对象hashcode值相同,不一定是同一个对象
hashmap底层是哈希列表,哈希列表中的哈希值
hashMap底层数据结构
HasgMap是基于哈希表的Map接口的非同步实现,此实现提供1所有可选的映射操作,并允许使用null值与null键,此类不保证映射的顺序,特别是它不保证该顺序永久不变
HashMap的数据结构实际上是一个链表散列的数据结构,即数组和链表的结合体
HashMap基于Hash算法实现的,我们通过put存储,get键赖获取,当传入key时,HashMap会根据key的hashCode()计算出hash值,根据hash值将value保存在bucket里,当计算出的hash值相同时,我们称为hash冲突,HashMap的做法时用链表和红黑树存储相同hash值得value。当hash冲突得个数比较少时,使用连表否则使用红黑树
线程安全得集合,HashTable,但HashTable访问速度慢,底层用得Synchronized关键字。HashTable虽然线程安全,但他有性能问题有一个更好得集合,就是juc包下得ConcurrentHashMap得类型
ConcurrentHashMap与HashMap等得区别
1.HashMap:
HashMap底层是数组+链表实现得,是线程不安全得,在多线程环境下,使用Hashmap进行put操作会引起死循环,导致cpu接近百分之百,所以在并发情况下不能使用HashMap
2.HashTable:
HashTable和hashMap得实现原理几乎一样,差别无非是HashTable不运行键和值为空,而hashmap允许,hashtable是线程安全得,但hashtable线程安全得策略实现代价太大,简单粗暴,get/put所有相关操作都上锁,多线程访问时,只要有一个线程访问,其他线程就只能阻塞
3.ConcurrentHashMap:
主要就是为了应对hashmap在并发环境下不安全而诞生得,ConcurrentHashMap得设计与实现非常好,大量得利用了volatlle,final,CAS等lock-free技术来减少锁带来得影响
1.简述集合体系?
集合分为单列集合和双列集合。
单列集合的顶层是Collection接口,包括List和Set集合。
List集合的特点是元素可重复,有序,有索引,能够有角标操作集合,有特有的迭代方式ListIterator。包括ArrayList、LinkedList和Vector。
ArrayList集合底层采用的是数组数据结构,查询速度比较快,因为数组有索引,在内存中分配的空间是连续的,但是增删比较慢。线程不同步,效率高。初始容量为10。
LinkedList集合的底层采用的是链表数据结构,增删速度比较快,查询速度比较慢。线程不同步。
Vector底层数据结构也是数组数据结构,但是线程同步,效率低,特有取出元素的方式是枚举。因为效率低,逐步被ArrayList替代。
Set集合的特点元素是无序的(存入和取出的顺序不一致),元素不可以重复。包括HashSet和TreeSet。
HashSet的底层数据结构是哈希表,线程不同步,效率高。保证元素的唯一性额有的依据是元素的hashCode和equals方法。如果hashCode不同,不调用equals方法。如果hashCode相同,才会调用equals方法判断元素是否相同。
TreeSet的底层数据结构是二叉树,线程不同步,效率高。能够给元素进行排序。保证元素唯一性的依据是compareTo和return0。排序的两种方式:第一种元素自身实现Comparable接口,重写compareTo()方法。这种排序方式叫元素的自然排序,也叫默认排序。第二种是当元素自身不具备比较性或者具备的比较性不是所需要的,这时就让集合自身具备比较性,当集合初始化时就有了比较性。定义一个比较器实现Comparator接口,重写compare方法,定义集合的时候将比较器作为参数传递给TreeSet的构造函数,这样集合就具有了比较性。
Map是双列集合的顶层接口,该集合存储的是键值对,一对一对的往里存,而且要保证键的唯一性。包括Hashtable、HashMap、TreeMap。
Hashtable的底层数据结构是哈希表,不可以存储null键和null值,线程同步,效率低。JDK1.0.
HashMap的底层数据结构是哈希表,可以存储null键和null值,线程不同步,将Hashtable替代,JDK1.2效率高。保证键的唯一性的依据是hashCode和equals方法。
TreeMap的底层数据结构是二叉树,线程不安全,能够给集合中的键排序。
2.什么时候使用什么集合?
(1)首先要看是单列还是双列,是单列的话就用Collection,双列就用Map。
(2)要是单列的话看元素是不是要求重复,元素重复的话使用List,看查询多还是增删多,查询多的话用ArrayList,增删多的话用LinkedList,不确定的话用ArrayList。不重复的话使用Set,看是否要求排序,排序的话用TreeSet,不需要排序用HashSet。不确定的话用HashSet。
(3)要是双列的话,看是否要求排序,要求排序用TreeMap,不要求排序用HashMap,不确定的话用HashMap。
3.Collection(单列)和(Map)双列的区别?
Collection是单列集合,Map是双列集合。
Map的键是唯一的,Collection体系中的Set集合中的元素是唯一的。
Map集合的数据结构针对键有效,Collection的底层数据结构针对元素有效。
4.遍历集合的方式有哪些?
遍历List集合的方式有普通for、增强for、迭代器Iterator、列表迭代器ListIterator。
遍历Set集合的方式有增强for、迭代器Iterator。
遍历map集合的方式有keySet(),entrySet()。然后通过增强for、迭代器Iterator遍历。
5.用迭代器和增强for遍历集合,能否用集合的方法操作集合?
不能,会出现并发修改异常,ConcurrentModificationException。并发修改异常就是在用普通迭代器的时候用集合的方法增加、删除元素。可以用列表迭代器。