All

迭代器
2019 年 08 月 28 日

迭代器

在java中主要有两种迭代器,IteratorListIterator。这两个都是接口。先来看一下这两个接口有什么区别

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public interface Iterator<E> {
    
    boolean hasNext();

    E next();
    
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

Iterator主要有四个方法。判断有没有下一个元素、获取下一个元素,删除元素和forEachRemaining方法。

再来看一下ListIterator

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public interface ListIterator<E> extends Iterator<E> {

    boolean hasNext();

    E next();

    boolean hasPrevious();

    E previous();

    int nextIndex();

    int previousIndex();

    void remove();

    void set(E e);

    void add(E e);
}

我们可以看到他是继承了Iterator。除了上面的两个方法还多了好几个方法。判断是否有上一个元素,获取上一个元素的值,获取上一个元素的索引,获取上一个元素的索引。除了移除还有添加和更新的方法。

他们在不同的类里面都有自己的实现,之前看ArrayListHashMap的时候把这一块给跳过了,现在来看一下他们是如何实现的。

HashSet源码
2019 年 08 月 26 日
HashMap源码学习
2019 年 08 月 22 日

HashMap结构

画了一张结构图,欢迎指正。

变量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* The default initial capacity - MUST be a power of two.
* 默认的容量,容量必须是2的幂
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

/**
* The maximum capacity, used if a higher value is implicitly specified
* by either of the constructors with arguments.
* MUST be a power of two <= 1<<30.
* 最大的容量值 2的30次幂
*/
static final int MAXIMUM_CAPACITY = 1 << 30;

/**
* The load factor used when none specified in constructor.
* 默认的负载系数
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;

/**
* The bin count threshold for using a tree rather than list for a
* bin.  Bins are converted to trees when adding an element to a
* bin with at least this many nodes. The value must be greater
* than 2 and should be at least 8 to mesh with assumptions in
* tree removal about conversion back to plain bins upon
* shrinkage.
* 链表的长度到达8之后转换为红黑树
*/
static final int TREEIFY_THRESHOLD = 8;

/**
* The bin count threshold for untreeifying a (split) bin during a
* resize operation. Should be less than TREEIFY_THRESHOLD, and at
* most 6 to mesh with shrinkage detection under removal.
*/
static final int UNTREEIFY_THRESHOLD = 6;

/**
* The smallest table capacity for which bins may be treeified.
* (Otherwise the table is resized if too many nodes in a bin.)
* Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts
* between resizing and treeification thresholds.
* 
*/
static final int MIN_TREEIFY_CAPACITY = 64;

// 存储的容器
transient Node<K,V>[] table;

/**
* Holds cached entrySet(). Note that AbstractMap fields are used
* for keySet() and values().
*/
transient Set<Map.Entry<K,V>> entrySet;

/**
* The number of key-value mappings contained in this map.
*/
transient int size;

/**
* The number of times this HashMap has been structurally modified
* Structural modifications are those that change the number of mappings in
* the HashMap or otherwise modify its internal structure (e.g.,
* rehash).  This field is used to make iterators on Collection-views of
* the HashMap fail-fast.  (See ConcurrentModificationException).
* 结构修改的次数,每次增加和删除都修改这个数值
*/
transient int modCount;

/**
* The next size value at which to resize (capacity * load factor).
*
* @serial
*/
// (The javadoc description is true upon serialization.
// Additionally, if the table array has not been allocated, this
// field holds the initial array capacity, or zero signifying
// DEFAULT_INITIAL_CAPACITY.)
// 扩容的阈值,当键值对的数量超过这个值就会扩容
int threshold;

/**
* The load factor for the hash table.
* 负载系数
*/
final float loadFactor;
LinkedHashMap源码
2019 年 08 月 22 日

LinkedHashMap结构图

LinkedHashMap继承了HashMap类,实现了Map接口。

他与HashMap的主要区别就是使用链表存储了每个节点的顺序。这样就能保证有序。

来看一下他的节点情况:

1
2
3
4
5
6
static class Entry<K,V> extends HashMap.Node<K,V> {
    Entry<K,V> before, after;
    Entry(int hash, K key, V value, Node<K,V> next) {
        super(hash, key, value, next);
    }
}

从这里可以看出他使用了两个变量,beforeafter存储这个节点的前后顺序。

LinkedList源码学习
2019 年 08 月 21 日

LinkedList使用了链表实现,相比ArrayList来说,插入更快,查看较慢。

首先看一下使用的链表结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
private static class Node<E> {
	E item;
	Node<E> next;
	Node<E> prev;

	Node(Node<E> prev, E element, Node<E> next) {
		this.item = element;
		this.next = next;
		this.prev = prev;
	}
}

每个Node节点存储一个元素,item表示这个元素的值,prev表示上一个元素,如果已经的第一个了那么为null。同理,next表示的是下一个元素,当插入新元素时会改变上一个元素的next值指向自己,这样就把这个链表串起来了。

变量

1
2
3
4
5
6
// 元素的数量
transient int size = 0;
// 指向第一个元素
transient Node<E> first;
// 指向最后一个元素
transient Node<E> last;
Mysql的ibtmp1文件过大
2019 年 08 月 21 日
ArrayList源码学习
2019 年 08 月 20 日

变量

1
2
3
4
5
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData; 
private int size;
  • DEFAULT_CAPACITY:默认的容量,当我们不指定容量时默认容量是10
  • EMPTY_ELEMENTDATA:空的数据集
  • DEFAULTCAPACITY_EMPTY_ELEMENTDATA:同上面的一样,都是空的数据集
  • elementData:保存的元素
  • size:元素长度,实际存储的元素数量

构造方法:

  • 无参的构造方法
1
2
3
public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

很简单的一句话,将保存元素的变量进行初始化。

两数相加-LeetCode2
2019 年 08 月 20 日

题目描述

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807

树莓派使用笔记
2019 年 08 月 08 日
重复N次的元素-LeetCode961
2019 年 08 月 08 日

题目描述

在大小为 2N 的数组 A 中有 N+1 个不同的元素,其中有一个元素重复了 N 次。

返回重复了 N 次的那个元素。

示例 1:

输入:[1,2,3,3] 输出:3 示例 2:

输入:[2,1,2,5,3,2] 输出:2 示例 3:

输入:[5,1,5,2,5,3,5,4] 输出:5

提示:

4 <= A.length <= 10000 0 <= A[i] < 10000 A.length 为偶数

大小为2N的数字中有个N+1个元素,其中有个元素重复了N次,这也说明了除了这个元素其他元素都没有重复,也可以理解成查找重复的元素