Java集合总结

1.java类集产生——JDK1.2
* 动态数组:解决数组定长问题
*
*Collection接口 单个对象保存的最顶层父接口
*
*
* Collection接口以及其子接口
* 在每次进行数据操作时候只能对单个对象进行处理
*
* 泛型避免了向下转型,再jdk1.5产生,专门为类集服务,而类集再1.2产生
* Collection继承了Iterator接口,在jdk1.5产生,为了遍历集合,内部只有一个方法
* Iterator<T>iterator(),取得集合的迭代器
*
* Collection中提供的核心方法:
* add,remove,contains,toArray(与双向链表类似)
* Collection只定义了存储数据的标准,但是无法区分存储类型,也无法区分数据是否,重复,所以派生了两个子接口
* 因此在实际中往往使用两个子接口List(允许数据重复),Set(不允许数据重复),一般不直接使用Collection接口
* 2.List(80%)--允许数据重复
* 在进行单个集合的处理时候,优先考虑List接口
* 在List接口中,拓展了两个重要方法(List接口独有)
* public E get(int index):根据索引下标去的数据 **********************
* public E Set(int index,E element):跟据索引下标更新数据 **********************
* 返回修改前的数据
* List接口的三大子类:ArrayList(90%),LinkedList,Vector,小向上自动转型
* ArrayList:add,contains,size,remove(索引下标,从0开始),get(size-1), set(size-1,修改后的值)但打印结果后
* 返回的是修改之前的值
* list接口要想保存自定义类的对象(contains方法,remove方法),该类必须覆写equals()来使用,
* 因为remove,contains方法里面需要用到equals来比较对象
* 然而系统给定的包装类(Integer类等)已经覆写了equals类,也就无需像自定义类一样重新覆写
* list.contains(new Person("name",age)),list.remove(new Person("name",age))
* 怎么覆写equals方法:
     @Override
    public boolean equals(Object obj) {
    //Object类到自定义类需要强转
         if(obj == this){
             return true;
       }
         else if(obj == null){
            return false;
         }
         else if(!(obj instanceof  Class)){
             return false;
        }
         //Object向下转型还原为Person类对象
         Person per = (Person) obj;
         return this.age.equals(per.age)&&this.name.equals(per.name);
     }
Set接口,不允许数据重复(Set集合的本质是map)
Set接口没有扩充方法

Set接口常用子类
HashSet(无序存储,本质上就是HashMap),允许add null,只能加一个null 1.底层使用哈希表+红黑树. 2.允许存放null,无序存储

TreeSet(有序存储,按照存放的先后,本质上就是HashMap):Comparable,Comparator 1.底层使用红黑树,2.不允许存放null,有序存储,自定义类
要想保存到TreeSet中,要么实现Comparable接口,要么向TreeSet传入比较器(Comparator接口)、

集合输出,迭代器输出,为了遍历集合而生
Iterator,Scanner实现了Iterator接口,Iterator的核心方法:
boolean hasNext();判断是否还有元素
E next();取得下一个元素

for循环遍历本质,是各个集合都有迭代器

Iterator 只能从前向后输出

调用Collection集合子类的Iterator方法取得内置的迭代器,使用以下输出格式(只有set和list有)
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){System.out.println(iterator.next());}

双向迭代器·接口ListIterator
除了hasNext与next方法外
hasPrevious():判断是否有上一个元素
previous:取得上一个元素
ListIterator<String> iterator = list.listIterator();
while(iterator.hasPrevious()){System.out.println(iterator.previous());}
要想使用从后向前遍历输出,首先至少从前向后遍历一次才可使用

Enumeration枚举输出--Vector类支持(1.0,古老版本没有类集)
hasMoreElements();判断是否有下一个元素
nextElements();取得下一个元素

for-each输出(所有子类都满足)
本质在于各个集合类都内置了迭代器

Map集合
Map接口是java中保存二元偶对象(键值对)的最顶层接口

public interface Map<K,V>
key值唯一,通过一个key值一定可以找到一个value值

Map接口的核心方法

public V put(K key,V value):向map中添加数据 当key值重复,再次put变为相应value的更新操作
public V get(K key):跟据指定的key值取得相应的value值
若没有此key值,返回null
public Set<Map.Entry<K,V>> entrySet //将Map集合变为Set集合
Set<Integer> keySet = map.keySet();
Iterator<Integer> iterator = keySet.iterator();
while(iteratot.hasNext()){
System.out.println(iterator.next());
}

public Set(K) keySet() :返回所有key值集合,key不能重复
public Collection<V> values():返回所有value值,value可以重复


Map接口的使用(Map中无迭代器),
Map接口有如下四个常用子类:
HashMap(使用频率最高),TreeMap,Hashtable,ConcurrentHashMap


** HashMap --类比HashSet

HashMap(jdk 1.2): 1.版本号1.2 2.允许key和value为null,且key值有且仅有一个为null,value可以有任意多个为null
效率高,线程不安全 4.底层哈希表+红黑树(jdk8)

Hashtable(jdk 1.0):1.版本号1.0 2.key与value均不能为null,3.synchronized修饰,使用方法加锁,效率低,线程安全
4.底层哈希表

比较接口  -TreeSet,TreeMap
Comparable(内部排序) int compareTo(Object obj);返回值为int,默认升序排序
Comparator(外部排序) int compare(Object ob1,Object obj2);返回值为int,排序灵活

HashSet,HashMap(Map为最顶层接口,无任何父接口)
hashCode:求哈希码
equals

equals相等的两个对象,hashCode一定保证相等
hashCode相同的两个对象,equals不一定相等
Collection中保存的是一个一个的具体对象,Map保存的是一个一个的Entry(Map.Entry(key,value))对象

****Map集合使用迭代器(Iterator--只与Collection接口有关系,而与Map接口没关系)输出
* 那么Map如何使用迭代器输出?
* Set<Map.Entry><K,V>>entrySet():将Map集合转为Set集合:

栈与队列
* 栈:先入后出
* 函数栈帧 浏览器标签页的后退,编辑器撤销
* 在面试题中:Stack类已经存在(jdk1.0,是Vector的子类,也是一个动态数组)
* Stack类:
* 入栈:push()
* 出栈:pop() 当栈为空的时候,会抛出栈为空的异常
* 返回栈顶元素但不出栈:peek()
* size()
*
* 自己实现一个html识别器
* <html>
* <head></head>
* <body></body>
* </html>
*
*
*
* 队列FIFO:选入先出
* 队列场景:买票,吃海底捞,消息队列(kafka)
*
* Queue接口 -LinkedList
* Queue<Integer> queue = new LinkedList<>();
* 入队列:add()
* 出队列:poll()
* 返回队列头元素,不出队:peek()

集合排序 Collection.sort(集合名称)  集合反转 Collections.reverse(集合名称)
Stream流(jdk8新增):Collection接口
核心方法:取得Stream流
Stream<E> Stream()
常用方法:forEach:集合输出

HashMap源码解析
* 什么时候是一个链表?什么时候是一个树?
* 桶的默认初始化容量2^4,16, 最大2^30, 默认负载因子为0.75
* 链表长度是8时,可能会树化
* 当树的节点数由大于等于8变为6时候,会非树化(变为链表)
* int hash 与桶放的位置有关,每put后会hash出来int的值(key==null的时候hash值为0),
* 将值赋给h,再把h向右移动16位,赋值完成后位32位,再向右移动16位,//--高16位为0,再和原来的值异或,
* 0和任何值取异或为0,所以高16位不参与运算--//,得到hash 的int值,新容量为16
* 新与值为16*0.75=12
*
* hash计算方法为了桶的均匀分布
*
* 当通过key与value的值计算出来的hash一样时候,就会放到相应的桶下形成一个链表
*
* entrySet 帮我们缓存所有的节点 其中 int size int modcount 并发修改 ,final float loadFactor
* final修饰,其默认值并不为0,需要通过构造方法或构造块进行初始化,具体值并不知道
* 此时hashmap实例化对象完成,size为0,与值为0, table数组为null, 负载因子为0.75
* table数组为0,说明new 完后桶并没有创建好,第一次添加元素的时候才会创建桶(put())
posted @ 2019-07-25 01:39  何浩源  阅读(251)  评论(0编辑  收藏  举报
//一下两个链接最好自己保存下来,再上传到自己的博客园的“文件”选项中