//以添加元素add方法为例
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node l = last; //最后一个节点
final Node newNode = new Node<>(l, e, null);//创建新节点
last = newNode; //新创建的节点赋值给全局变量last
if (l == null)
first = newNode; //如果最后一个节点为空,说明是第一次添加元素,把newNode当做第一个节点,赋值给全局变量first
else
l.next = newNode;//如果最后一个节点不为空,把newNode当做最后一个节点next变量的指针。
size++; //集合长度加1
modCount++; //修改数加1
}
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public class TreeSetTest {
public static void test() {
TreeSet treeSet = new TreeSet(new Person());
treeSet.add(new Person(12));
treeSet.add(new Person(20));
treeSet.add(new Person(50));
Iterator iterator = treeSet.iterator();
while (iterator.hasNext()) {
Person person = iterator.next();
System.out.println(person.getAge());//依次输出50、20、12
}
}
static final class Person implements Comparator {
public Person() {
}
public Person(int age) {
this.age = age;
}
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compare(Object o1, Object o2) {
Person p1 = (Person) o1;
Person p2 = (Person) o2;
return p2.getAge() - p1.getAge();//降序
}
}
transient Node<K,V>[] table; //全局表对象
static class Node<K,V> implements Map.Entry<K,V> {
final int hash; //哈希值
final K key; //键
V value; //值
Node<K,V> next; //下一个节点引用
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey() { return key; }
public final V getValue() { return value; }
public final String toString() { return key + "=" + value; }
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}
}
** HashMap中put方法解析**
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
//根据key生成hash值
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
//根据hash、key、value进行的实质的写操作
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0) //判断table是否为空
n = (tab = resize()).length; //初始化table或者调整table大小
if ((p = tab[i = (n - 1) & hash]) == null) //根据索引判断数组中元素是否为null
tab[i] = newNode(hash, key, value, null); //创建表节点,并给table中的元素赋值
else { //这个分支处理hash值重复问题
Node<K,V> e; K k;
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) //判断是否为覆盖模式,由onlyIfAbsent控制
e.value = value; //将新的值覆盖旧的值
afterNodeAccess(e);
return oldValue;
}
}
++modCount; //记录修改记录
if (++size > threshold) //判断表大小是否超过阀值,threshold是一个阀值
resize(); //调整表大小
afterNodeInsertion(evict);
return null;
}
public static void test() {
EnumMap enumMap = new EnumMap(Color.class);
enumMap.put(Color.BLUE, "blue");
enumMap.put(Color.RED, "red");
Set<Map.Entry> set = enumMap.entrySet();
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Map.Entry entry=(Map.Entry) iterator.next();
System.out.println(entry.getKey()+" "+entry.getValue());
/** 依次输出(按枚举类Color中元素的顺序输出,并不是按put的顺序)
* RED red
* BLUE blue
*/
}
}
enum Color {
RED, GREEN, BLUE
}
public static void test() {
ConcurrentSkipListMap concurrentSkipListMap = new ConcurrentSkipListMap(new Person());
concurrentSkipListMap.put(new Person(12), "gg");
concurrentSkipListMap.put(new Person(33), "55");
concurrentSkipListMap.put(new Person(1), 1);
Iterator iterator = concurrentSkipListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
Person person=(Person) entry.getKey();
System.out.println(person.getAge()+" "+entry.getValue());
/**依次输出,按Person中的排序规则进行排序
33 55
12 gg
1 1
*/
}
}
static final class Person implements Comparator {
public Person() {
}
public Person(int age) {
this.age = age;
}
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compare(Object o1, Object o2) {
Person p1 = (Person) o1;
Person p2 = (Person) o2;
return p2.getAge() - p1.getAge();//降序
}
}
**put方法解析**
public V put(K key, V value) {
if (value == null)
throw new NullPointerException();
return doPut(key, value, false);
}
private V doPut(K key, V value, boolean onlyIfAbsent) {
...省略
z = new Node<K,V>(key, value, n);
if (!b.casNext(n, z)) //写入
break; // restart if lost race to append to b
break outer;
...省略
}
**get方法解析**
public V get(Object key) {
return doGet(key);
}
private V doGet(Object key) {
if (key == null)
throw new NullPointerException();
Comparator<? super K> cmp = comparator;
outer: for (;;) {
for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) { //取值
Object v; int c;
if (n == null)
break outer;
Node<K,V> f = n.next;
if (n != b.next) // inconsistent read
break;
if ((v = n.value) == null) { // n is deleted
n.helpDelete(b, f);
break;
}
if (b.value == null || v == n) // b is deleted
break;
if ((c = cpr(cmp, key, n.key)) == 0) {
@SuppressWarnings("unchecked") V vv = (V)v; //赋值
return vv;
}
if (c < 0)
break outer;
b = n;
n = f;
}
}
return null;
}
public V put(K key, V value) {
final Object k = maskNull(key);//处理null的情况,如果key为null,创建一个Object对象
retryAfterResize: for (;;) {
final Object[] tab = table;
final int len = tab.length;
int i = hash(k, len); //根据key和表的长度计算哈希值
for (Object item; (item = tab[i]) != null;
i = nextKeyIndex(i, len)) { //根据计算出来的哈希值i作为索引去表tab中查找元素
if (item == k) {//如果根据哈希值i在表中找到了元素,则通过**内存地址**的比较,元素是否是本身
@SuppressWarnings("unchecked")
V oldValue = (V) tab[i + 1]; //获取旧值
tab[i + 1] = value; //重新赋值
return oldValue; //返回旧的值
}
}
final int s = size + 1; //大小+1
// Use optimized form of 3 * s.
// Next capacity is len, 2 * current capacity.
if (s + (s << 1) > len && resize(len)) //判断是否需要调整大小
continue retryAfterResize;
modCount++; //操作记录+1
tab[i] = k; //存储键到表中
tab[i + 1] = value; 存储值到表中
size = s; //集合大小赋值到全局变量size
return null;
}
}
//哈希函数
private static int hash(Object x, int length) {
int h = System.identityHashCode(x);//这个方法是原生方法,返回对象的hashCode,而不管对象是否重写了hashCode方法。(物理内存地址产生的哈希值)
// Multiply by -127, and left-shift to use least bit as part of hash
return ((h << 1) - (h << 8)) & (length - 1);
}
**IdentityHashMap中get方法分析**
public V get(Object key) {
Object k = maskNull(key);//处理null情况
Object[] tab = table;
int len = tab.length;
int i = hash(k, len); //根据哈希函数获取哈希值,和put方法调用的哈希函数一致
while (true) {
Object item = tab[i]; //根据哈希值i获取表中元素(该位置存的是键)
if (item == k) //内存地址比较
return (V) tab[i + 1]; //如果相等则从表中取出元素并返回
if (item == null) //未找到元素
return null;
i = nextKeyIndex(i, len); //处理哈希冲突问题
}
}
public V get(Object key) {
Entry<K,V> p = getEntry(key);
return (p==null ? null : p.value);
}
final Entry<K,V> getEntry(Object key) {
// Offload comparator-based version for sake of performance
if (comparator != null)
return getEntryUsingComparator(key);
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
Entry<K,V> p = root; //获取树根节点
while (p != null) { //通过大小比较,不断遍历树
int cmp = k.compareTo(p.key); //比较大小
if (cmp < 0) //k<p.key
p = p.left; //继续比较左子树
else if (cmp > 0) //k>p.key
p = p.right;//继续比较右子树
else
return p; //找到节点返回
}
return null;
}
**TreeMap中remove方法分析**
public V remove(Object key) {
Entry<K,V> p = getEntry(key); //查找树节点,和get方法一致的逻辑
if (p == null)
return null;
V oldValue = p.value; //获取元素的值
deleteEntry(p);
return oldValue; //返回被移除元素的值
}
// If strictly internal, copy successor's element to p and then make p
// point to successor.
if (p.left != null && p.right != null) {//当前节点存在左子树和右子树的情况
Entry<K,V> s = successor(p);
p.key = s.key;
p.value = s.value;
p = s;
} // p has 2 children
// Start fixup at replacement node, if it exists.
Entry<K,V> replacement = (p.left != null ? p.left : p.right); //查找替换节点,p的左子树或者右子树
if (replacement != null) {
// Link replacement to parent
replacement.parent = p.parent; //交换父亲
if (p.parent == null) //p为根节点情形
root = replacement;
else if (p == p.parent.left)//当前节点向左倾斜,即当前节点是其父亲的左子树
p.parent.left = replacement; //交换位置
else//当前节点向右倾斜,即当前节点是其父亲的右子树
p.parent.right = replacement; //交换位置
// Null out links so they are OK to use by fixAfterDeletion.
p.left = p.right = p.parent = null; //置空节点元素
// Fix replacement
if (p.color == BLACK)
fixAfterDeletion(replacement); //调整树节点颜色
} else if (p.parent == null) { // return if we are the only node.
root = null;
} else { // No children. Use self as phantom replacement and unlink. //没有子节点情形
if (p.color == BLACK) //判断节点颜色
fixAfterDeletion(p);
if (p.parent != null) {
if (p == p.parent.left) //当前节点向左倾斜,即当前节点是其父亲的左子树
p.parent.left = null;//直接置空删除
else if (p == p.parent.right) //当前节点向右倾斜,即当前节点是其父亲的右子树
p.parent.right = null; //直接置空删除
p.parent = null; //直接置空
}
}
}
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(12);
list.add(5);
list.add(1);
Collections.sort(list);//支持自定义排序调用重载方法sort(List<T> list, Comparator<? super T> c)
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
**线程安全处理举例**
List list = new ArrayList();
list.add(1);
list.add(2);
list = Collections.synchronizedList(list); //Collections内部通过synchronized关键字保证线程安全
**二分查找举例**
List list = new ArrayList<>();
list.add(1);
list.add(12);
list.add(5);
list.add(10);
Collections.sort(list);//1,5,10,12
int res= Collections.binarySearch(list,5);//返回元素的位置索引
System.out.println(res);
ArrayList list = new ArrayList();
list.add("aa");
list.add("bb");
list.add("cc");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String tmp=(String) iterator.next();
if(tmp=="aa"){
list.remove(tmp);//这句代码会导致java.util.ConcurrentModificationException
}
}
System.out.println(list.size());
**情形2**
ArrayList list = new ArrayList();
list.add("aa");
list.add("bb");
list.add("cc");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String tmp=(String) iterator.next();
if(tmp=="aa"){
iterator.remove(); //通过迭代器的方式提供的方法就不会抛出异常
}
}
System.out.println(list.size());
**针对情形1和情形2,剖析下Fail-Fast在ArrayList中的实现原理**
public Iterator iterator() {
return new Itr();
}
//迭代器实现类
private class Itr implements Iterator {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount; //把全局的变量modCount赋值给expectedModCount
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification(); //这个方法是关键,会检查expectedModCount和全局变量modCount是否相等,不相等就抛出ConcurrentModificationException异常
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() { //这个方法是迭代器提供的方法
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet); //根据索引移除元素
cursor = lastRet; //更新游标变量
lastRet = -1;
expectedModCount = modCount; //将最新的modCount赋值给变量expectedModCount
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
public Iterator iterator() {
return new COWIterator(getArray(), 0); //将集合数组传入构造方法
}
static final class COWIterator implements ListIterator {
/* Snapshot of the array /
private final Object[] snapshot; //内部类缓存了一份数组的快照
/* Index of element to be returned by subsequent call to next. /
private int cursor;
private COWIterator(Object[] elements, int initialCursor) {
cursor = initialCursor;
snapshot = elements;
}
public boolean hasNext() {
return cursor < snapshot.length; //使用的是数组快照
}
@SuppressWarnings("unchecked")
public E next() {
if (! hasNext())
throw new NoSuchElementException();
return (E) snapshot[cursor++]; ////使用的是数组快照
}
}
// 1.内部类私有化(封装)
private class Inner_Demo {
public void print() {
System.out.println("This is an inner class ");
}
}
//对外暴露的方法
void display_Inner() {
Inner_Demo inner = new Inner_Demo();
inner.print();
}
// 2.内部类公有化(对外暴露)
public class Inner_Demo2 {
public int getNum() {
System.out.println("This is the getnum method of the inner class");
return num;
}
}
}
**使用普通内部类**
//类型1
Outer_Demo outer = new Outer_Demo();
outer.display_Inner();
//类型2
Outer_Demo.Inner_Demo2 inner_demo2 = new Outer_Demo().new Inner_Demo2();
inner_demo2.getNum();
class Outer_Demo {
//静态内部类
static class StaticClassDemo {
public void my_method() {
System.out.println("This is static class");
}
}
}
//调用静态内部类
public static void main(String args[]) {
Outer_Demo.StaticClassDemo staticClassDemo = new Outer_Demo.StaticClassDemo();
staticClassDemo.my_method();
}
- **方法内部类:** 方法内部类是指在类的方法中定义的类;如下所示:
class Outer_Demo {
void my_Method() {
int num = 23;
// 方法内部类
class MethodInner_Demo {
public void print() {
System.out.println("This is method inner class "+num);
}
}
// 访问内部类
MethodInner_Demo inner = new MethodInner_Demo();
inner.print();
}
}
//通常定义为接口或者抽象类
abstract class AnonymousInner {
public abstract void mymethod();
}
public class Outer_class {
public static void main(String args[]) {
//创建匿名内部类和初始化
AnonymousInner inner = new AnonymousInner() {
public void mymethod() {
System.out.println("This is an example of anonymous inner class");
}
};
//调用匿名内部类中的方法
inner.mymethod();
}
}
在java中主要有单列集合Collection和双列集合Map。接下来介绍下这两大集合的技术体系。
1. Collection(接口)
Collection是单列集合的顶层接口,定义了基本的添加、删除、查找、遍历等接口方法。
1.1 List(接口)
List表示有序的集合,用户可以通过使用索引来查找元素。接下来了解下List集合的子类或者子接口,如下:
ArrayList(类):ArrayList是一个数组实现的集合,其继承链为List(接口)-> AbstractCollection(类)-> AbstractList(类)-> ArrayList(类);ArrayList内部支持动态扩容、查询效率高、增删效率低。 接下来介绍下ArrayList源码中动态扩容机制,默认容量10,如下所示:
private void ensureExplicitCapacity(int minCapacity) { modCount++;//表示执行次数
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length;//数组的长度 int newCapacity = oldCapacity + (oldCapacity >> 1);//(oldCapacity >> 1)是大于或等于0的整数(等于oldCapacity除以2的一次方) if (newCapacity - minCapacity < 0) //比较大小 newCapacity = minCapacity;//如果minCapacity大于newCapacity ,即进行赋值操作 if (newCapacity - MAX_ARRAY_SIZE > 0)//newCapacity 和MAX_ARRAY_SIZE 比较,其中MAX_ARRAY_SIZE =Integer.MAX_VALUE - 8 newCapacity = hugeCapacity(minCapacity);//如果newCapacity大于MAX_ARRAY_SIZE,就交换大小 // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity);//按新的容量大小newCapacity重新生成数组 }
//双链表的节点 private static class Node {
E item; //存储元素本身
Node next; //下一个节点的引用
Node prev;//上一个节点的引用
//以添加元素add方法为例 public boolean add(E e) { linkLast(e); return true; }
void linkLast(E e) { final Node l = last; //最后一个节点
final Node newNode = new Node<>(l, e, null);//创建新节点
last = newNode; //新创建的节点赋值给全局变量last
if (l == null)
first = newNode; //如果最后一个节点为空,说明是第一次添加元素,把newNode当做第一个节点,赋值给全局变量first
else
l.next = newNode;//如果最后一个节点不为空,把newNode当做最后一个节点next变量的指针。
size++; //集合长度加1
modCount++; //修改数加1
}
public static void test() { try { RoleList roleList = new RoleList(); List roleValues = new ArrayList<>();
roleValues.add(new ObjectName("ADD"));
roleValues.add(new ObjectName("DELETE"));
Role role = new Role("admin", roleValues);
roleList.add(role);
} catch (MalformedObjectNameException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean add(E e) { final ReentrantLock lock = this.lock; lock.lock();//加锁 try { Object[] elements = getArray();//获取原始数组 int len = elements.length;//获取原始数组长度 Object[] newElements = Arrays.copyOf(elements, len + 1);//通过拷贝的方式创建新数组,新数组长度+1 newElements[len] = e;//给新数组最后一个元素赋值 setArray(newElements);//设置回全局的数组变量 return true; } finally { lock.unlock();//释放锁 } }
private transient HashMap<E,Object> map; //HashSet中的HashMap全局变量map,用于HashSet的增、删、查等操作
//LinkedHashSet.java public LinkedHashSet() { super(16, .75f, true); }
//HashSet.java HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); //从调用来看源码中使用的是LinkedHashMap类来实现的集合操作 }
//自定义排序 public class ConcurrentSkipListSetTest {
}
package collection.set;
import java.util.EnumSet; import java.util.Iterator;
public class EnumSetTest {
}
//通过实现接口Comparator自定义排序 package collection.set;
import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet;
public class TreeSetTest { public static void test() { TreeSet treeSet = new TreeSet(new Person());
treeSet.add(new Person(12));
treeSet.add(new Person(20));
treeSet.add(new Person(50));
Iterator iterator = treeSet.iterator();
while (iterator.hasNext()) {
Person person = iterator.next();
System.out.println(person.getAge());//依次输出50、20、12
}
}
}
transient Node<K,V>[] table; //全局表对象 static class Node<K,V> implements Map.Entry<K,V> { final int hash; //哈希值 final K key; //键 V value; //值 Node<K,V> next; //下一个节点引用
public V put(K key, V value) { return putVal(hash(key), key, value, false, true); }
//根据key生成hash值 static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
//根据hash、key、value进行的实质的写操作 final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; if ((tab = table) == null || (n = tab.length) == 0) //判断table是否为空 n = (tab = resize()).length; //初始化table或者调整table大小 if ((p = tab[i = (n - 1) & hash]) == null) //根据索引判断数组中元素是否为null tab[i] = newNode(hash, key, value, null); //创建表节点,并给table中的元素赋值 else { //这个分支处理hash值重复问题 Node<K,V> e; K k; 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) //判断是否为覆盖模式,由onlyIfAbsent控制 e.value = value; //将新的值覆盖旧的值 afterNodeAccess(e); return oldValue; } } ++modCount; //记录修改记录 if (++size > threshold) //判断表大小是否超过阀值,threshold是一个阀值 resize(); //调整表大小 afterNodeInsertion(evict); return null; }
static class Entry<K,V> extends HashMap.Node<K,V> { //继承HashMap.Node Entry<K,V> before, after; //双链表结构每个元素保存上一个和下一个元素的引用 Entry(int hash, K key, V value, Node<K,V> next) { super(hash, key, value, next); } }
//这个方法是HashMap中的方法 public V put(K key, V value) { return putVal(hash(key), key, value, false, true); }
//这个方法是HashMap中的方法 final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null);//newNode()是调用LinkedHashMap中的方法 else { Node<K,V> e; K k; ........省略部分代码 }
//LinkedHashMap中重写父类HashMap中的方法 Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) { LinkedHashMap.Entry<K,V> p = new LinkedHashMap.Entry<K,V>(hash, key, value, e); linkNodeLast(p); //添加新节点到链表中 return p; }
//添加节点到链表最后 private void linkNodeLast(LinkedHashMap.Entry<K,V> p) { LinkedHashMap.Entry<K,V> last = tail; //tail表示链表尾巴节点 tail = p; if (last == null) head = p; else { p.before = last; last.after = p; } }
public V get(Object key) { Node<K,V> e; if ((e = getNode(hash(key), key)) == null) //这里调用父类HashMap中的getNode方法 return null; if (accessOrder) //accessOrder表示访问顺序,true表示集合按访问的顺序迭代,true表示按元素添加的顺序迭代 afterNodeAccess(e); return e.value; }
//LinkedHashMap构造方法 public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {//accessOrder表示访问顺序,true表示集合按访问的顺序迭代,true表示按元素添加的顺序迭代 super(initialCapacity, loadFactor); this.accessOrder = accessOrder; }
//将访问的元素移到链表最后 void afterNodeAccess(Node<K,V> e) { // move node to last LinkedHashMap.Entry<K,V> last;//最后的元素 if (accessOrder && (last = tail) != e) { LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after; //p表示当前操作的元素,b表示p的前一个元素节点,a表示p的后一个元素节点 p.after = null; //移到链表最后,after指针置为null if (b == null) head = a; //表示当前访问的元素是第一个元素,交换指针,把a变成链表第一个元素 else b.after = a;//不是第一个元素,交换位置 if (a != null) a.before = b;//不是最后一个元素,交换位置 else last = b;//这个分支不会执行 if (last == null) head = p;//当前元素就是第一个元素 else { p.before = last; //和最后一个元素交换位置 last.after = p; } tail = p; //当前元素变成链表最后 ++modCount; //修改记录数+1 }
public EnumMap(Class keyType) {
this.keyType = keyType; //keyType是枚举类型,K extends Enum
keyUniverse = getKeyUniverse(keyType);//获取枚举类
vals = new Object[keyUniverse.length]; //根据枚举类的元素个数创建数组
}
public V put(K key, V value) { typeCheck(key); //检查key类型是否为枚举类型
private void typeCheck(K key) { Class<?> keyClass = key.getClass(); if (keyClass != keyType && keyClass.getSuperclass() != keyType) throw new ClassCastException(keyClass + " != " + keyType); }
private V unmaskNull(Object value) { return (V)(value == NULL ? null : value); }
public V get(Object key) { return (isValidKey(key) ? unmaskNull(vals[((Enum<?>)key).ordinal()]) : null); //先判断key的合法性,再根据数组索引取值 }
private boolean isValidKey(Object key) { if (key == null) return false;
private V unmaskNull(Object value) { return (V)(value == NULL ? null : value); }
public V put(K key, V value) { return putVal(key, value, false); }
final V putVal(K key, V value, boolean onlyIfAbsent) { if (key == null || value == null) throw new NullPointerException(); int hash = spread(key.hashCode()); //计算key的哈希值 int binCount = 0; for (Node<K,V>[] tab = table;;) {//table存储数据的表 Node<K,V> f; int n, i, fh; if (tab == null || (n = tab.length) == 0) tab = initTable();//初始化表 else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { //获取指定偏移量对象的引用 if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value, null)))//添加新元素 break; // no lock when adding to empty bin } else if ((fh = f.hash) == MOVED) tab = helpTransfer(tab, f); else { //处理键相同的问题,即重复给相同key赋值 V oldVal = null; synchronized (f) { if (tabAt(tab, i) == f) { if (fh >= 0) { binCount = 1; for (Node<K,V> e = f;; ++binCount) { K ek; if (e.hash == hash && ((ek = e.key) == key || (ek != null && key.equals(ek)))) { oldVal = e.val; if (!onlyIfAbsent) e.val = value; break; } Node<K,V> pred = e; if ((e = e.next) == null) { pred.next = new Node<K,V>(hash, key, value, null); break; } } } else if (f instanceof TreeBin) { Node<K,V> p; binCount = 2; if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key, value)) != null) { oldVal = p.val; if (!onlyIfAbsent) p.val = value; } } } } if (binCount != 0) { if (binCount >= TREEIFY_THRESHOLD) treeifyBin(tab, i); if (oldVal != null) return oldVal; break; } } } addCount(1L, binCount); return null; }
//取值 static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) { return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE); } //写入 static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i, Node<K,V> c, Node<K,V> v) { return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v); }
//存取的偏移量都是 ((long)i << ASHIFT) + ABASE,这个偏移量用于从内存中取值。
public V get(Object key) { Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek; int h = spread(key.hashCode()); //计算key对应的哈希值 if ((tab = table) != null && (n = tab.length) > 0 && (e = tabAt(tab, (n - 1) & h)) != null) { //根据相同的偏移量调用tabAt方法取值 if ((eh = e.hash) == h) { if ((ek = e.key) == key || (ek != null && key.equals(ek))) return e.val; } else if (eh < 0) return (p = e.find(h, key)) != null ? p.val : null; while ((e = e.next) != null) { if (e.hash == h && ((ek = e.key) == key || (ek != null && key.equals(ek)))) return e.val; } } return null; }
ConcurrentSkipListMap concurrentSkipListMap = new ConcurrentSkipListMap(); concurrentSkipListMap.put(2, "gg"); concurrentSkipListMap.put(3, "55"); concurrentSkipListMap.put(1, 1);
public static void test() { ConcurrentSkipListMap concurrentSkipListMap = new ConcurrentSkipListMap(new Person()); concurrentSkipListMap.put(new Person(12), "gg"); concurrentSkipListMap.put(new Person(33), "55"); concurrentSkipListMap.put(new Person(1), 1);
public V put(K key, V value) { if (value == null) throw new NullPointerException(); return doPut(key, value, false); }
private V doPut(K key, V value, boolean onlyIfAbsent) { ...省略 z = new Node<K,V>(key, value, n); if (!b.casNext(n, z)) //写入 break; // restart if lost race to append to b break outer; ...省略 }
public V get(Object key) { return doGet(key); }
private V doGet(Object key) { if (key == null) throw new NullPointerException(); Comparator<? super K> cmp = comparator; outer: for (;;) { for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) { //取值 Object v; int c; if (n == null) break outer; Node<K,V> f = n.next; if (n != b.next) // inconsistent read break; if ((v = n.value) == null) { // n is deleted n.helpDelete(b, f); break; } if (b.value == null || v == n) // b is deleted break; if ((c = cpr(cmp, key, n.key)) == 0) { @SuppressWarnings("unchecked") V vv = (V)v; //赋值 return vv; } if (c < 0) break outer; b = n; n = f; } } return null; }
public V put(K key, V value) { final Object k = maskNull(key);//处理null的情况,如果key为null,创建一个Object对象
//哈希函数 private static int hash(Object x, int length) { int h = System.identityHashCode(x);//这个方法是原生方法,返回对象的hashCode,而不管对象是否重写了hashCode方法。(物理内存地址产生的哈希值) // Multiply by -127, and left-shift to use least bit as part of hash return ((h << 1) - (h << 8)) & (length - 1); }
public V get(Object key) { Object k = maskNull(key);//处理null情况 Object[] tab = table; int len = tab.length; int i = hash(k, len); //根据哈希函数获取哈希值,和put方法调用的哈希函数一致 while (true) { Object item = tab[i]; //根据哈希值i获取表中元素(该位置存的是键) if (item == k) //内存地址比较 return (V) tab[i + 1]; //如果相等则从表中取出元素并返回 if (item == null) //未找到元素 return null; i = nextKeyIndex(i, len); //处理哈希冲突问题 } }
static final class Entry<K,V> implements Map.Entry<K,V> { K key; //键 V value; //值 Entry<K,V> left; //左子树 Entry<K,V> right; //右子树 Entry<K,V> parent; //父节点 boolean color = BLACK; //颜色标识 //省略其他代码 }
public V put(K key, V value) { Entry<K,V> t = root; //根节点 if (t == null) { //第一个添加元素 compare(key, key); // type (and possibly null) check
//修改节点插入的位置 private void fixAfterInsertion(Entry<K,V> x) { x.color = RED; //BLACK表示true,RED表示false;这里给节点设置初始值
//向右偏转(处理思路和rotateLeft方法类似) private void rotateRight(Entry<K,V> p) { if (p != null) { Entry<K,V> l = p.left; p.left = l.right; if (l.right != null) l.right.parent = p; l.parent = p.parent; if (p.parent == null) root = l; else if (p.parent.right == p) p.parent.right = l; else p.parent.left = l; l.right = p; p.parent = l; } }
public V get(Object key) { Entry<K,V> p = getEntry(key); return (p==null ? null : p.value); }
final Entry<K,V> getEntry(Object key) { // Offload comparator-based version for sake of performance if (comparator != null) return getEntryUsingComparator(key); if (key == null) throw new NullPointerException(); @SuppressWarnings("unchecked") Comparable<? super K> k = (Comparable<? super K>) key; Entry<K,V> p = root; //获取树根节点 while (p != null) { //通过大小比较,不断遍历树 int cmp = k.compareTo(p.key); //比较大小 if (cmp < 0) //k<p.key p = p.left; //继续比较左子树 else if (cmp > 0) //k>p.key p = p.right;//继续比较右子树 else return p; //找到节点返回 } return null; }
public V remove(Object key) { Entry<K,V> p = getEntry(key); //查找树节点,和get方法一致的逻辑 if (p == null) return null;
//删除节点并重新调整树节点 private void deleteEntry(Entry<K,V> p) { modCount++;//修改记录+1 size--;//集合大小-1
private static class Entry<K,V> extends WeakReference
}
Attributes attributes=new Attributes(); Attributes.Name name=new Attributes.Name("name"); Attributes.Name age=new Attributes.Name("age"); attributes.put(name,"zgq"); attributes.put(age,"20");
public SimpleBindings() { this(new HashMap<String,Object>()); }
public SimpleBindings(Map<String,Object> m) { if (m == null) { throw new NullPointerException(); } this.map = m; }
//从源码来看,SimpleBindings就是一个包装类,其实现取决于构造方法传入的对象。
RenderingHints renderingHints = new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); renderingHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
Properties properties=new Properties(); properties.setProperty("key1","value1"); properties.setProperty("key2","value2"); try { OutputStream outputStream = new FileOutputStream("D:\aa.txt"); properties.store(outputStream,"file");//持久化到文件
List list = new ArrayList<>();
list.add(1);
list.add(12);
list.add(5);
list.add(10);
Collections.sort(list);//1,5,10,12
int res= Collections.binarySearch(list,5);//返回元素的位置索引
System.out.println(res);
ArrayList list = new ArrayList(); list.add("aa"); list.add("bb"); list.add("cc"); Iterator iterator = list.iterator(); while (iterator.hasNext()) { String tmp=(String) iterator.next(); if(tmp=="aa"){ list.remove(tmp);//这句代码会导致java.util.ConcurrentModificationException } } System.out.println(list.size());
public Iterator iterator() {
return new Itr();
}
//迭代器实现类 private class Itr implements Iterator {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount; //把全局的变量modCount赋值给expectedModCount
//集合移除方法remove public boolean remove(Object o) { //。。。 fastRemove(index); //这个方法导致全局变量modCount值发生变化 //。。。 }
private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }
public Iterator iterator() {
return new COWIterator(getArray(), 0); //将集合数组传入构造方法
}
static final class COWIterator implements ListIterator {
/* Snapshot of the array /
private final Object[] snapshot; //内部类缓存了一份数组的快照
/* Index of element to be returned by subsequent call to next. /
private int cursor;
public boolean equals(Object anObject) { if (this == anObject) { //内存地址的比较 return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { //字符串中逐个字符的比对,每个字符都相等equals返回true,否者返回false if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
class Student { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Student() { } public Student(String name) { this.name = name; } }
class Student { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Student() { } public Student(String name) { this.name = name; } @Override public int hashCode() { int hash = 10; if (name != null) { hash = 31 * hash + name.hashCode(); } return hash; }
public V get(Object key) { Node<K,V> e; return (e = getNode(hash(key), key)) == null ? null : e.value; }
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); // key.hashCode()这句代码是关键,如果子类没有重写Object中hashCode方法,则这里调用的是Object中的hashCode方法 }
class Outer_Demo { private int num = 10;
}
class Outer_Demo { //静态内部类 static class StaticClassDemo { public void my_method() { System.out.println("This is static class"); } } }
//调用静态内部类 public static void main(String args[]) { Outer_Demo.StaticClassDemo staticClassDemo = new Outer_Demo.StaticClassDemo(); staticClassDemo.my_method(); }
class Outer_Demo { void my_Method() { int num = 23; // 方法内部类 class MethodInner_Demo { public void print() { System.out.println("This is method inner class "+num); } } // 访问内部类 MethodInner_Demo inner = new MethodInner_Demo(); inner.print(); } }
//通常定义为接口或者抽象类 abstract class AnonymousInner { public abstract void mymethod(); }
public class Outer_class { public static void main(String args[]) { //创建匿名内部类和初始化 AnonymousInner inner = new AnonymousInner() { public void mymethod() { System.out.println("This is an example of anonymous inner class"); } }; //调用匿名内部类中的方法 inner.mymethod(); } }