以前讲了两种List,一种基于数组实现的ArrayList,一种基于链表实现的LinkedList,这两种list是咱们工做中最经常使用到的List容器。固然数组和链表也是两种常见的基本数据结构,其余基本数据结构还有堆栈、队列、树等,对java容器的学习,也能够看作是对数据结构的学习和使用。java
1
2
|
public
class
ArrayList<E>
extends
AbstractList<E>
implements
List<E>, RandomAccess, Cloneable, java.io.Serializable
|
LinkedList的定义:编程
1
2
3
|
public
class
LinkedList<E>
extends
AbstractSequentialList<E>
implements
List<E>, Deque<E>, Cloneable, java.io.Serializable
|
从定义上能够看到ArrayList和LinkedList都实现了List接口,ok看下List接口的定义:设计模式
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
|
public
interface
List<E>
extends
Collection<E> {
int
size();
boolean
isEmpty();
boolean
contains(Object o);
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] a);
boolean
add(E e);
boolean
remove(Object o);
boolean
containsAll(Collection<?> c);
boolean
addAll(Collection<?
extends
E> c);
boolean
addAll(
int
index, Collection<?
extends
E> c);
boolean
removeAll(Collection<?> c);
boolean
retainAll(Collection<?> c);
void
clear();
boolean
equals(Object o);
int
hashCode();
E get(
int
index);
E set(
int
index, E element);
void
add(
int
index, E element);
E remove(
int
index);
int
indexOf(Object o);
int
lastIndexOf(Object o);
ListIterator<E> listIterator();
ListIterator<E> listIterator(
int
index);
List<E> subList(
int
fromIndex,
int
toIndex);
}
|
能够看到List中对容器的各类操做add、remove、set、get、size等进行了统必定义,同时List实现了Collection接口,继续看下Collection接口的定义(先不关心Iterator):数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public
interface
Collection<E>
extends
Iterable<E> {
int
size();
boolean
isEmpty();
boolean
contains(Object o);
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] a);
boolean
add(E e);
boolean
remove(Object o);
boolean
containsAll(Collection<?> c);
boolean
addAll(Collection<?
extends
E> c);
boolean
removeAll(Collection<?> c);
boolean
retainAll(Collection<?> c);
void
clear();
boolean
equals(Object o);
int
hashCode();
}<span style=
"font-weight: normal;"
> </span>
|
有了这两个接口,对于ArrayList和LinkeList的操做是否是就能够这么写了呢?数据结构
1
2
3
4
|
Collection<String> collection =
new
ArrayList<String>();
collection.add(
"hello"
);
collection.add(
"java"
);
collection.remove(
"hello"
);
|
对于ArrayList的实现不满意,ok换成LinkedList实现,多线程
1
2
3
4
|
Collection<String> collection =
new
LinkedList<String>();
collection.add(
"hello"
);
collection.add(
"java"
);
collection.remove(
"hello"
);
|
对于用户来讲,add、remove等操做是没有任何影响的,好了,到这里了解了统一接口,面向接口编程的好处,接下来在思考另一个问题,怎么给容器提供一种遍历方式。dom
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/** Implementing this interface allows an object to be the target of
* the "foreach" statement.
* @since 1.5
*/
public
interface
Iterable<T> {
/**
* Returns an iterator over a set of elements of type T.
*
* @return an Iterator.
*/
Iterator<T> iterator();
}
|
英文注释说,实现iterable接口的类可使用“foreach”操做,而后并要求实现Iterator<T> iterator()方法,该方法返回一个Iterator接口对象,来看下Iterator接口,ide
1
2
3
4
5
6
7
8
|
public
interface
Iterator<E> {
// 是否还有元素
boolean
hasNext();
// 下一个元素
E next();
// 将迭代器返回的元素删除
void
remove();
}
|
Iterator接口一共有三个方法,经过这三个方法就能够实现通用遍历了,ok,咱们来试一下。学习
1
2
3
4
5
6
7
8
|
Collection<String> collection =
new
ArrayList<String>();
collection.add(
"hello"
);
collection.add(
"java"
);
Iterator<String> iterator = collection.iterator();
while
(iterator.hasNext()) {
System. out.println(iterator.next());
}
|
1
2
3
4
|
public
interface
MyIterator {
Object next();
boolean
hasNext();
}
|
容器统一接口:this
1
2
3
4
5
|
public
interface
MyCollection {
void
add(Object o);
int
size();
MyIterator iterator();
}
|
容器实现类和Iterator实现类(Iterator实现类为容器内部类):
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
|
public
class
MyArrayList
implements
MyCollection {
private
Object[] data ;
private
int
size;
public
MyArrayList() {
data =
new
Object[
10
];
}
public
void
add(Object o) {
if
(size == data. length) {
Object[] newData =
new
Object[data .length *
2
];
System. arraycopy(data,
0
, newData,
0
, data.length );
data = newData;
}
data[size ] = o;
size++;
}
public
int
size() {
return
size ;
}
@Override
public
MyIterator iterator() {
return
new
Itr();
}
private
class
Itr
implements
MyIterator {
private
int
index =
0
;
@Override
public
boolean
hasNext() {
if
(index >= size) {
return
false
;
}
else
{
return
true
;
}
}
@Override
public
Object next() {
Object o = data[index ];
index++;
return
o;
}
}
}
|
应用一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
class
Test {
public
static
void
main(String[] args) {
MyCollection c =
new
MyArrayList();
c.add(
"t"
);
c.add(
"s"
);
c.add(
"t"
);
c.add(
"d"
);
System. out.println(c.size());
MyIterator itr = c.iterator();
while
(itr.hasNext()) {
System. out.println(itr.next());
}
}
}
|
1
2
3
4
5
|
4
t
s
t
d
|
没问题,很容易就实现了对不对,固然这里只是简单模拟,没有过多的追求效率和优雅的设计。
1
2
3
|
public
Iterator<E> iterator() {
return
new
Itr();
}<span style=
"font-weight: normal;"
> </span>
|
和本身实现的同样,采用内部类实现 Iterator接口。
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
|
private
class
Itr
implements
Iterator<E> {
// 将要next返回元素的索引
int
cursor =
0
;
// 当前返回的元素的索引,初始值-1
int
lastRet = -
1
;
/**
* The modCount value that the iterator believes that the backing
* List should have. If this expectation is violated, the iterator
* has detected concurrent modification.
*/
int
expectedModCount = modCount;
public
boolean
hasNext() {
// 因为cursor是将要返回元素的索引,也就是下一个元素的索引,和size比较是否相等,也就是判断是否已经next到最后一个元素
return
cursor != size();
}
public
E next() {
checkForComodification();
try
{
// 根据下一个元素索引取出对应元素
E next = get( cursor);
// 更新lastRet为当前元素的索引,cursor加1
lastRet = cursor ++;
// 返回元素
return
next;
}
catch
(IndexOutOfBoundsException e) {
checkForComodification();
throw
new
NoSuchElementException();
}
}
public
void
remove() {
// remove前必须先next一下,先取得当前元素
if
(lastRet == -
1
)
throw
new
IllegalStateException();
checkForComodification();
try
{
AbstractList.
this
.remove(lastRet );
// 确保lastRet比cursor小、理论上永远lastRet比cursor小1
if
(lastRet < cursor)
// 因为删除了一个元素cursor回退1
cursor--;
// 重置为-1
lastRet = -
1
;
expectedModCount = modCount ;
}
catch
(IndexOutOfBoundsException e) {
throw
new
ConcurrentModificationException();
}
}
final
void
checkForComodification() {
if
(modCount != expectedModCount)
throw
new
ConcurrentModificationException();
}
}
|
1
2
3
|
public
Iterator<E> iterator() {
return
listIterator();
}
|
AbstractList的实现:
1
2
3
4
5
6
7
8
9
|
public
ListIterator<E> listIterator() {
return
listIterator(
0
);
}
public
ListIterator<E> listIterator(
final
int
index) {
if
(index<
0
|| index>size())
throw
new
IndexOutOfBoundsException(
"Index: "
+index);
return
new
ListItr(index);
}
|
看一下ListItr实现:
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
private
class
ListItr
implements
ListIterator<E> {
// 最后一次返回的节点,默认位header节点
private
Entry<E> lastReturned = header;
// 将要返回的节点
private
Entry<E> next ;
// 将要返回的节点index索引
private
int
nextIndex;
private
int
expectedModCount = modCount;
ListItr(
int
index) {
// 索引越界检查
if
(index <
0
|| index > size)
throw
new
IndexOutOfBoundsException(
"Index: "
+index+
", Size: "
+size );
// 简单二分,判断遍历的方向
if
(index < (size >>
1
)) {
// 取得index位置对应的节点
next = header .next;
for
(nextIndex =
0
; nextIndex<index; nextIndex++)
next = next .next;
}
else
{
next = header ;
for
(nextIndex =size; nextIndex>index; nextIndex --)
next = next .previous;
}
}
public
boolean
hasNext() {
// 根据下一个节点index是否等于size,判断是否有下一个节点
return
nextIndex != size;
}
public
E next() {
checkForComodification();
// 遍历完成
if
(nextIndex == size)
throw
new
NoSuchElementException();
// 赋值最近一次返回的节点
lastReturned = next ;
// 赋值下一次要返回的节点(next后移)
next = next .next;
// 将要返回的节点index索引+1
nextIndex++;
return
lastReturned .element;
}
public
boolean
hasPrevious() {
return
nextIndex !=
0
;
}
// 返回上一个节点(双向循环链表嘛、能够两个方向遍历)
public
E previous() {
if
(nextIndex ==
0
)
throw
new
NoSuchElementException();
lastReturned = next = next. previous;
nextIndex--;
checkForComodification();
return
lastReturned .element;
}
public
int
nextIndex() {
return
nextIndex ;
}
public
int
previousIndex() {
return
nextIndex -
1
;
}
public
void
remove() {
checkForComodification();
// 取出当前返回节点的下一个节点
Entry<E> lastNext = lastReturned.next ;
try
{
LinkedList.
this
.remove(lastReturned );
}
catch
(NoSuchElementException e) {
throw
new
IllegalStateException();
}
// 确认下次要返回的节点不是当前节点,若是是则修正
if
(next ==lastReturned)
next = lastNext;
else
// 因为删除了一个节点,下次要返回的节点索引-1
nextIndex--;
// 重置lastReturned为header节点
lastReturned = header ;
expectedModCount++;
}
public
void
set(E e) {
if
(lastReturned == header)
throw
new
IllegalStateException();
checkForComodification();
lastReturned.element = e;
}
public
void
add(E e) {
checkForComodification();
lastReturned = header ;
addBefore(e, next);
nextIndex++;
expectedModCount++;
}
final
void
checkForComodification() {
if
(modCount != expectedModCount)
throw
new
ConcurrentModificationException();
}
}<span style=
"font-weight: normal;"
> </span>
|