集合的相关知识点
Posted Camellia——
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了集合的相关知识点相关的知识,希望对你有一定的参考价值。
1.集合分为两组:单列集合(单个的对象)、双列集合(以键值对的方式存在)
2.Collection接口有两个重要的子接口List、Set,他们的实现子类都是单列集合
1)有些可以存放重复的元素,有些不可以存放
2)List有序,Set无序
3)通过子接口Set和List实现的
3.Map接口的实现子类是双列集合,存放的K-V
4.List集合的特点:
1.添加和取出的顺序一致且可以重复
2.List集合每个元素都有其对应顺序索引,支持索引取出
5.ArrayList底层源码分析
1.ArrayList中维护了一个Object类型的数组elementData
2.当创建ArrayList对象时,如果使用的是无参构造,
则初始elementData容量为0
第一次添加,则扩容elementData为10,
如果需要再次扩容,则扩容elementData为1.5倍
3.如果使用指定大小的构造器,则初始化elementData容量为指定大小,
如果需要扩容,则直接扩容elementData为1.5倍
6.Vector的基本介绍
1.Vector底层也是一个对象数组
2.Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized
安全且效率不高
7.LinkedList的全面说明
1.LinkedList底层实现了双向链表和双端队列的特点
2.LinkedList中维护了两个属性first和last分别指向首节点和尾节点
3.每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过pre指向前一个,通过next指向后一个节点。最终实现双向链表
4.LinkedList的元素的添加和删除功能不是通过数组完成的,相对来说效率较高
8. ArrayList和LinkedList(都是线程不安全的)
1.如果我们改查的操作多,选择ArrayList
2.如果我们增删的操作多,选择LinkedList
3.在程序中,大部分都是查询,因此大部分情况下会选择ArrayList
9.set接口的基本介绍
1.无序(添加和取出的顺序不一致)且取出的顺序是固定的,没有索引
2.不允许重复元素,最多包含一个null
3.JDK API中set的接口实现类:AbstractSet,
ConcurrentSkipListSet,
CopyOnWriteArraySet, EnumSet, HashSet,
JobStateReasons, LinkedHashSet, TreeSet
4.set的接口遍历方式:迭代器、增强for,不能使用索引的方式来获取
10.HashSet的特点
1.HashSet实现了Set接口
2.HashSet实际上是HashMap,HashMap的底层是:数组+链表+红黑树
3.HashSet可以存放null,但是只能有一个null,即元素不能重复
4.HashSet不保证存放元素的顺序和取出顺序一致
5.不能有重复的元素/对象
6.经典面试题
set.add(new String("kk"));//ok
set.add(new String("kk"));//加入不了
7.HashSet的底层原理
1.HashSet底层是HashMap
2.添加一个元素时,先得到hash值会转成->索引值
3.找到存储数据表table,看到这个索引位置是否已经有元素存放
4.如果没有,直接加入
5.如果有,调用equals比较,如果相同,就放弃添加,如果不同则添加到最后
6.在Java8中,如果有一条链表的元素个数到达TREEIFY_THRESHOLD(默认是8)
并且table的大小>=MIN_TREEIFY_CAPACITY(默认64)就会进树化(红黑树)
11.对HashSet的源码解读
1.执行HashSet()
public HashSet()
map = new HashMap<>();
2.执行add()
public boolean add(E e)
return map.put(e, PRESENT)==null;//PRESENT起到占位的目的,
3.执行put(),该方法会执行hash(key)得到key对应的hash值,与hash算法得到的值有区别
public V put(K key, V value) //value=PRESENT起到占位的目的,
return putVal(hash(key), key, value, false, true);
4.执行
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict)
Node<K,V>[] tab; Node<K,V> p; int n, i;//定义了辅助性的变量
//table就是HashMap的一个数组,类型是Node[]
//if语句表示如果当前table是null,或者 大小=0,就进行一次扩容,到16
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
//(1)根据key得到的hash去计算key应该存放到table表的哪个索引位置
//并把这个位置的对象赋给P
//(2)判断P是否为null
//(2.1)如果p为null,就表示没有存放元素,就创建一个Node
//(2.2)就放在该位置tab[i]=newNode(hash, key, value, null)
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else
Node<K,V> e; K k;
//如果当前索引位置对应的链表的第一个元素和准备添加的key的hash值一样
//并且满足 下面条件之一:
//(1)准备加入的key和P指向的Node节点的key是同一个对象
//(2)P指向的Node节点的key的equals()和准备加入的key比较后相同
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else
for (int binCount = 0; ; ++binCount)
if ((e = p.next) == null)
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
if (e != null) // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
12.HashSet底层扩容机制和树化
1.HashSet底层是HashMap,第一次添加时table数组扩容到16,临界值
(threshold)16*加载因子 16*0.75=12
2.如果table数组使用到了临界值12,就会扩容到16*2=32,新的临界值
就是32*0.75=24,依次类推
3.在Java8中,如果一条链表的元素个数到达TREEIFY_THRESHOLD(默认值8),
并且table的大小>=MIN_TREEIFY_CAPACITY(默认64)就会进树化(红黑树),
否则任然采用数组扩容机制
13.LinkedHashSet说明
1.在LinkedHashSet底层是一个LinkedHashMap维护了一个数组和双向链表
2.每个节点都有before和after属性,这样可以形成双向链表
3.在添加元素时先求,hash值。在求索引,确定该元素在table位置,如果已经存在不添加
4.同时确保插入顺序和遍历顺序的一致性,且元素不能重复
14.Map,接口实现类的特点,使用实现类HashMap
1.Map和Collection并列存在,用于保存具有映射关系的数据Key-Value(双列元素)
2.Map中的Key和Value可以是任何引用类型的数据,会封装到HashMap$Node对象中
3.Map中的key不允许重复,当有相同的K,就等价于替换
4.Map中的value是可以重复的
5.Map中的Key和Value都可以为空,Key为空只能有一个Value为空可以有多个
6.常用String作为Key,其他类型也可以
15.HashMap特点
1.K-V最后存放在是HashMap$Node node=newNode(hash,key,value,null)
2.K-V为了方便程序员的遍历,还会创建EntrySet集合,该集合存放元素的类型
Entry,而一个Entry对象就有k,v
3.entrySet中,定义的类型是Map.Entry,但是实际上存放的还是HashMap$Node
因为Node实现了Map.Entry
4.当把HashMap$Node对象存放到entrySet就方便遍历,entrySet提供
了两个重要的方法,getKey();getValue
16.Map接口的常用方法
remove:根据键删除映射关系
get:根据键获取值
size:获取元素个数
isEmpty:判断个数是否为 0
clear:清除 k-v
containsKey:查找键是否存在
17.map遍历的六大方式
public class MapFor
public static void main(String[] args)
Map map = new HashMap();
map.put("刘令博", null);//OK
map.put(null, "刘亦菲");//OK
map.put("鹿晗", "关晓彤");//OK
//第一组:通过key取出value值
Set set = map.keySet();
// (1)增强for
for (Object key : set)
System.out.println(key+"=="+map.get(key));
//(2)迭代器
Iterator iterator = set.iterator();
while (iterator.hasNext())
Object next = iterator.next();
System.out.println(next+"--"+map.get(next));
//第二组把所有的value取出来
Collection values = map.values();
// (1)增强for
for (Object value : values)
System.out.println(value);
// (2)迭代器
Iterator iterator1 = values.iterator();
while (iterator1.hasNext())
System.out.println(iterator1.next());
//第三组 :通过EntrySet
Set entrySet = map.entrySet();
//1.增强for
for (Object entry : entrySet)
Map.Entry m=(Map.Entry)entry;
System.out.println(m.getKey()+"**"+m.getValue());
//2.迭代器
Iterator iterator2 = entrySet.iterator();
while(iterator2.hasNext())
Object next = iterator2.next();
Map.Entry m=(Map.Entry)next;
System.out.println(m.getKey()+"&"+m.getValue());
18.HashMap小结
1.Map接口的常用实现类:HashMap、Hashtable和properties
2.HashMap经常使用
3.HashMap以键值对的方式存取
4.HashMap中的key不允许重复,当有相同的K,就等价于替换
5.HashMap与HashSet一样,不保证映射顺序,因为底层是以hash表
的方式存储的
6.HashMap没有实现线程同步机制,因此线程不安全,方法没有做到同步互斥
19.HashMap底层机制及源码剖析
1.HashMap底层维护了Node类型的数组table,默认为null
2.当创建对象时,将加载因子初始化为0.75
3.当添加k-v,如果k重复直接替换之前value的值;如果不相等判断是连败哦还是树
做出相应的处理
4.第一次添加,table的容量为16,临界值为12
5.再次扩容时table的值是原来的2倍,临界值为原来的两倍
6.在Java8中,一条链表的元素超过8个并且table的大小>=64,会进行树化
20.HashTable的基本介绍
1.存放的元素是键值对
2.hashtable的键和值都不能为空,否则会抛出异常,key相同时还是会替换
3.hashTable使用方法基本上和HashMap一样
4.hashTable是线程安全的(synchronized),hashMap是线程不安全的
21.HashTable的底层
1.底层有数组Hashtable$Entry[]初始化大小11
2.临界值threshold 8=11*0.75
3.扩容:是原来大小的两倍+1
22.集合选型规则
1.判断存储的类型(单例、双列)
2.一组对象[单列]Collection接口
允许重复:List
增删多:LinkedList(底层维护了一个双向链表)
改查多:ArrayList(底层维护了Object类型的可变数组)
不允许重复:Set
无序:HashSet(底层是HashMap,维护了一个哈希表(数组+链表+红黑树))
有序:TreeSet
插入和取出一致:LinkedHashSet,维护数组+双向链表
3.一组键值对:Map
键无序:HashMap(底层:哈希表jdk 7:数组+链表,jdk8:数组+链表+红黑树)
键排序:TreeMap
键的插入和取出顺序一致:LinkedHashMap
读取文件:properties
23.TreeSet底层
/*
* 1.构造器把传入的底层对象,给到底层的TreeMap
* 2.在底层加入 treeSet.add("b");
*if (cpr != null) //crp就是匿名内部类对象
do
parent = t;
cmp = cpr.compare(key, t.key);动态绑定compare
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else//如果相等这个数据加入不了
return t.setValue(value);
while (t != null);
*
* */
//比较的是字符串的长度,如果长度相同则加入失败
((String)o1).length()-((String)o2).length()
24.TreeSet源码解读
public class TreeMap_
public static void main(String[] args)
//默认无序指的是元素取出和添加的顺序不一致
/*TreeMap treeMap = new TreeMap();*/
TreeMap treeMap = new TreeMap(new Comparator()
@Override
public int compare(Object o1, Object o2)
return ((String)o1).length()-((String)o2).length();
);
treeMap.put("ea","ds");
treeMap.put("asd","da");
treeMap.put("bfff","db");
treeMap.put("cregg","dc");
treeMap.put("egrgre","de");
treeMap.put("ww","ds");//不是替换,直接加入不了
/*
* 解读源码:
* 1.执行构造器 把传入的实现了 Comparator的匿名内部类(对象)传给了TreeMap的comparator
* public TreeMap(Comparator<? super K> comparator)
this.comparator = comparator;
2.调用put方法
2.1第一次添加
* Entry<K,V> t = root;
if (t == null)
compare(key, key); // type (and possibly null) check 检测是否为空
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
2.2以后添加启用比较器
* //决定具体的位置
* if (cpr != null)
do
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
while (t != null);
*/
System.out.println(treeMap);
25.Collections工具类
1.Collections是一个操作Set、List、Map等集合的工具类
2.Collections中提供了一系列静态方法对集合元素进行排序查询
3.排序常用的方法
reverse(List):反转 List 中元素的顺
shuffle(List):对 List 集合元素进行随机排序
sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
4.查找替换常用的方法
/*1) Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
2) Object max(Collection,Comparator):根据Comparator指定的顺序,返回给定集合中的最大元素
3)Object min(Collection)
4)Object min(Collection,Comparator)
5)int frequency(Collection,Object):返回指定集合中指定元素的出现次数
6)void copy(List destList src):将src中的内容复制到dest中
7)boolean replaceAll(List list,Object oldValObject newVal)使用新值 替换 List 对象的所有旧值*/
javascript 相关小的知识点集合
本文主要是列出一些javascript 相关的,不限于javascript的,容易记错或者遗忘的小知识,小技巧。
1、javascript中的false
在 JavaScript,常见的 false 值:
0, \'0\', +0, -0, false, \'\',null,undefined,NaN
要注意空数组([])和空对象({}):
console.log([] == false) //true console.log({} == false) //false console.log(Boolean([])) //true console.log(Boolean({})) //true
所以在 if 中,[] 和 {} 都表现为 true。
2、禁用js
【设置】->【显示高级设置...】->点击【隐私设置】->【内容设置】->找到 【javascript】部分
3、HBuilder编辑器(国产)
内置了Emmet
emmet给css提升
ul>li*5
a[href="www.baidu.com"]
emmet给js提升
var box=dg按下tab
ifelse用法:ife
for循环:fori
预览快捷键:ctrl+r
字符串拼接时,选中一个变量,按\'就会在变量两边加上单引号。
4、javascript组成
ECMAScript+DOM+BOM
5、class是保留字
class是js中的保留字, 所以不允许用.class,用的都是className,比如getElementsByClassName。
6、innerHTML可以直接加标签
innerHTML里面有html标签时,会被解析成Html标签。
7、href和src和color
不用拿href和src和color取到的值做判断
pic.src这样
可以用getAttribute取。
8、控制台输出的字符串是黑色的,数字是蓝色的
var a="11"; var b=11; console.log(a); console.log(b);
9、留言板
box.innerHtml=box.innerHtml+\'<p>\'+val+\'</p>\';
var newText=\'<p>\'+val+\'</p>\';
box.innerHtml+=newText;
10、console.dir(arr)输出集合
var arr=[\'a\',12,\'b\',\'c\',\'e\']; console.log(arr); console.dir(arr);
11、灵活使用Math.min()和Math.max()
Math.min(0,1,4,3)//返回最小的
0
index--;
if(index<0){
index=0;
}
可以用下面一行替代上面多行
index=Max(0,--index);
本文作者starof,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:http://www.cnblogs.com/starof/p/6815775.html有问题欢迎与我讨论,共同进步。
以上是关于集合的相关知识点的主要内容,如果未能解决你的问题,请参考以下文章