链表:
List是一个有序集合,集合中元素是有位置之分的
Java中迭代器的位置是两个元素的中间
一些API的使用说明:
remove:会删除掉刚刚遍历过的元素
add:会在链表尾部增加元素
contains:判断一个元素在不在链表中
list.listIterator(n)会返回一个迭代器,在索引为n这个元素的前面
尽量不要用get方法来遍历链表(不能直接过去,需要从头遍历过去,有小优化,索引>size()/2从尾部遍历过去)
nextlndex会返回下一次调用next返回元素的下标(效率高)
如果想在链表中间插入元素,可以通过ListIterator这个类型的迭代器
1.通过迭代器在链表中间调用add,可以在迭代器左边的位置添加元素
2.可以反向遍历链表,previous和hasprevious
3.可以用ite.set(xx)替换刚刚遍历过的元素
为了避免并发操作集合引起的问题,可是创建多个迭代器只能读不能写,只有一个迭代器负责写。
数组:
Arraylist和Vector ,是有序集合
后者是线程安全的,所以单线程访问建议用Arraylist 效率高
前者扩容是扩大50%,后者是100%
哈希集:
hashtable,是一个无序集合
链表数组 在java SE 8中链表变成了平衡二叉树
树集:
TreeSet : 底层是红黑树,所以是有序的
添加一个元素比散列表慢很多,
树集的排序是一个很困难的事情,如果不需要还是用Hash比较好
映射:
可以通过get(key)来获取实值
或者put(key,value)来添加,如果已经存在对应的key了,那么value值将会覆盖
remove(key)会删除给定键对应的元素
更新映射项的方法:
counts.put(word,count.get(word)+1); 这种方法如果word不存在就会出现异常
方法一:
counts.put(word,count.getOrDefault(word,0)+1);如果这个键值不存在那么get返回值就是默认值(这里是0),否则返回对应的实值
方法二:
mp.putIfAbsent("hh",10);如果存在键值hh就什么都不做,不存在将实值设置为10
获取一个map中的所有键值:Set<String>keys = map.keySet();
获取一个map中的所有实值:Collection<Integer> aa = mp.values();
遍历这个map的键值对:
1. for(Map.Entry<String,Integer> entry:staff.entrySet())
{
entry.getKey();//获取键值
ntry.getValue();//获取实值
}
2. Iterator<Map.Entry<String ,Integer>> ite = mp.entrySet().iterator();
while(ite.hasNext())
{
Map.Entry<String ,Integer> Mydata = ite.next();
System.out.println(Mydata.getKey()+"-"+ Mydata.getValue());
ite.remove();//需要remove所以需要迭代器
}
弱散列映射:
如果我们将一个对象a以及他的引用A作为一个key值关联某个Value值后put入HashMap中,那么这个a对象的引用不仅仅有A,而且有一个HashMap中持有的引用,一共两个引用。WeakHashMap的原理也相同,此时在WeakHashMap中的a也持有两个引用,一个是A,另一个是WeakHashMap的散列表持有的引用。那么现在分析弱哈希映射表的原理:WeakHashMap散列表持有所有key的引用是弱引用。弱引用的概念是:如果一个对象仅有一个弱引用指向它,那么在下次GC进行回收时会将其回收。所以说,上述的a对象,如果A引用不再指向它,而且也没有其他的地方使用到a对象形成它的引用的话,在下一次垃圾回收时a对象表示的k-v对将被从WeakHashMap中删除。
深入理解HashMap的初始容量与负载因子:https://www.iteye.com/topic/539465
要保证初始容量*负载因子 > 元素个数,默认是16和0.75
LinkedHashMap是有序的,实际上双线链表与hashmap的结合,有两种形式
1.按照插入顺序(默认)
2.按照修改顺序呢,只要调用了put或者get方法,就会把这个节点放到双线链表的尾节点
如果需要第二种形式,需要在构造的时候设置accessOrder为true(默认是false为第一种方法)。