java 集合系列目录:

Java 集合系列 01 总体框架

Java 集合系列 02 Collection架构

Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例

Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例

Java 集合系列 05 Vector详细介绍(源码解析)和使用示例

Java 集合系列 06 Stack详细介绍(源码解析)和使用示例

Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和性能分析)

Java 集合系列 08 Map架构

Java 集合系列 09 HashMap详细介绍(源码解析)和使用示例

Java 集合系列 10 Hashtable详细介绍(源码解析)和使用示例

Java 集合系列 11 hashmap 和 hashtable 的区别

Java 集合系列 12 TreeMap

Java 集合系列 13 WeakHashMap

Java 集合系列 14 hashCode

Java 集合系列 15 Map总结

Java 集合系列 16 HashSet

Java 集合系列 17 TreeSet

概要 

和学习ArrayList一样,接下来呢,我们先对LinkedList有个整体认识,然后再学习它的源码;最后再通过实例来学会使用LinkedList。内容包括:
第1部分 LinkedList介绍
第2部分 LinkedList数据结构
第3部分 LinkedList源码解析(基于JDK1.7)
第4部分 LinkedList遍历方式

第1部分 LinkedList介绍

LinkedList简介

LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
LinkedList 实现 List 接口,能对它进行队列操作。
LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
LinkedList 是非同步的。

LinkedList构造函数

  1. // 默认构造函数
  2. LinkedList()
  3.  
  4. // 创建一个LinkedList,保护Collection中的全部元素。
  5. LinkedList(Collection<? extends E> collection)

LinkedList的API

  1. LinkedListAPI
  2. boolean add(E object)
  3. void add(int location, E object)
  4. boolean addAll(Collection<? extends E> collection)
  5. boolean addAll(int location, Collection<? extends E> collection)
  6. void addFirst(E object)
  7. void addLast(E object)
  8. void clear()
  9. Object clone()
  10. boolean contains(Object object)
  11. Iterator<E> descendingIterator()
  12. E element()
  13. E get(int location)
  14. E getFirst()
  15. E getLast()
  16. int indexOf(Object object)
  17. int lastIndexOf(Object object)
  18. ListIterator<E> listIterator(int location)
  19. boolean offer(E o)
  20. boolean offerFirst(E e)
  21. boolean offerLast(E e)
  22. E peek()
  23. E peekFirst()
  24. E peekLast()
  25. E poll()
  26. E pollFirst()
  27. E pollLast()
  28. E pop()
  29. void push(E e)
  30. E remove()
  31. E remove(int location)
  32. boolean remove(Object object)
  33. E removeFirst()
  34. boolean removeFirstOccurrence(Object o)
  35. E removeLast()
  36. boolean removeLastOccurrence(Object o)
  37. E set(int location, E object)
  38. int size()
  39. <T> T[] toArray(T[] contents)
  40. Object[] toArray()

AbstractSequentialList简介

在介绍LinkedList的源码之前,先介绍一下AbstractSequentialList。毕竟,LinkedList是AbstractSequentialList的子类。

AbstractSequentialList 实现了get(int index)、set(int index, E element)、add(int index, E element) 和 remove(int index)这些函数。这些接口都是随机访问List的,LinkedList是双向链表;既然它继承于AbstractSequentialList,就相当于已经实现了“get(int index)这些接口”。

此外,我们若需要通过AbstractSequentialList自己实现一个列表,只需要扩展此类,并提供 listIterator() 和 size() 方法的实现即可。若要实现不可修改的列表,则需要实现列表迭代器的 hasNext、next、hasPrevious、previous 和 index 方法即可。

第2部分 LinkedList数据结构

LinkedList的继承关系

  1. java.lang.Object
  2. java.util.AbstractCollection<E>
  3. java.util.AbstractList<E>
  4. java.util.AbstractSequentialList<E>
  5. java.util.LinkedList<E>
  6.  
  7. public class LinkedList<E>
  8. extends AbstractSequentialList<E>
  9. implements List<E>, Deque<E>, Cloneable, java.io.Serializable {}

LinkedList与Collection关系如下图:

第3部分 LinkedList源码解析(基于JDK1.7)

为了更了解LinkedList的原理,下面对LinkedList源码代码作出分析。

在阅读源码之前,我们先对LinkedList的整体实现进行大致说明:
    LinkedList实际上是通过双向链表去实现的。既然是双向链表,那么它的顺序访问会非常高效,而随机访问效率比较低
    既然LinkedList是通过双向链表的,但是它也实现了List接口{也就是说,它实现了get(int location)、remove(int location)等“根据索引值来获取、删除节点的函数”}。LinkedList是如何实现List的这些接口的,如何将“双向链表和索引值联系起来的”?
    实际原理非常简单,它就是通过一个计数索引值来实现的。例如,当我们调用get(int location)时,首先会比较“location”和“双向链表长度的1/2”;若前者大,则从链表头开始往后查找,直到location位置;否则,从链表末尾开始先前查找,直到location位置。
   这就是“双线链表和索引值联系起来”的方法。

好了,接下来开始阅读源码(只要理解双向链表,那么LinkedList的源码很容易理解的)。

有关LinkedList在JDK1.6和JDK1.7的区别以及优化,参看 JDK1.7-LinkedList循环链表优化,这里列出是1.7的源码

其中 Node:

  1. private static class Node<E> {
  2. E item;
  3. Node<E> next;
  4. Node<E> prev;
  5.  
  6. Node(Node<E> prev, E element, Node<E> next) {
  7. this.item = element;
  8. this.next = next;
  9. this.prev = prev;
  10. }
  11. }
  1. public class LinkedList<E>
  2. extends AbstractSequentialList<E>
  3. implements List<E>, Deque<E>, Cloneable, java.io.Serializable
  4. {
  5. transient int size = 0;
  6.  
  7. /**
  8. * Pointer to first node.
  9. * Invariant: (first == null && last == null) ||
  10. * (first.prev == null && first.item != null)
  11. */
  12. transient Node<E> first;
  13.  
  14. /**
  15. * Pointer to last node.
  16. * Invariant: (first == null && last == null) ||
  17. * (last.next == null && last.item != null)
  18. */
  19. transient Node<E> last;
  20.  
  21. /**
  22. * Constructs an empty list.
  23. */
  24. public LinkedList() {
  25. }
  26.  
  27. /**
  28. * Constructs a list containing the elements of the specified
  29. * collection, in the order they are returned by the collection's
  30. * iterator.
  31. *
  32. * @param c the collection whose elements are to be placed into this list
  33. * @throws NullPointerException if the specified collection is null
  34. */
  35. public LinkedList(Collection<? extends E> c) {
  36. this();
  37. addAll(c);
  38. }
  39.  
  40. /**
  41. * Links e as first element.
  42. */
  43. private void linkFirst(E e) {
  44. final Node<E> f = first;
  45. final Node<E> newNode = new Node<>(null, e, f);
  46. first = newNode;
  47. if (f == null)
  48. last = newNode;
  49. else
  50. f.prev = newNode;
  51. size++;
  52. modCount++;
  53. }
  54.  
  55. /**
  56. * Links e as last element.
  57. */
  58. void linkLast(E e) {
  59. final Node<E> l = last;
  60. final Node<E> newNode = new Node<>(l, e, null);
  61. last = newNode;
  62. if (l == null)
  63. first = newNode;
  64. else
  65. l.next = newNode;
  66. size++;
  67. modCount++;
  68. }
  69.  
  70. /**
  71. * Inserts element e before non-null Node succ.
  72. */
  73. void linkBefore(E e, Node<E> succ) {
  74. // assert succ != null;
  75. final Node<E> pred = succ.prev;
  76. final Node<E> newNode = new Node<>(pred, e, succ);
  77. succ.prev = newNode;
  78. if (pred == null)
  79. first = newNode;
  80. else
  81. pred.next = newNode;
  82. size++;
  83. modCount++;
  84. }
  85.  
  86. /**
  87. * Unlinks non-null first node f.
  88. */
  89. private E unlinkFirst(Node<E> f) {
  90. // assert f == first && f != null;
  91. final E element = f.item;
  92. final Node<E> next = f.next;
  93. f.item = null;
  94. f.next = null; // help GC
  95. first = next;
  96. if (next == null)
  97. last = null;
  98. else
  99. next.prev = null;
  100. size--;
  101. modCount++;
  102. return element;
  103. }
  104.  
  105. /**
  106. * Unlinks non-null last node l.
  107. */
  108. private E unlinkLast(Node<E> l) {
  109. // assert l == last && l != null;
  110. final E element = l.item;
  111. final Node<E> prev = l.prev;
  112. l.item = null;
  113. l.prev = null; // help GC
  114. last = prev;
  115. if (prev == null)
  116. first = null;
  117. else
  118. prev.next = null;
  119. size--;
  120. modCount++;
  121. return element;
  122. }
  123.  
  124. /**
  125. * Unlinks non-null node x.
  126. */
  127. E unlink(Node<E> x) {
  128. // assert x != null;
  129. final E element = x.item;
  130. final Node<E> next = x.next;
  131. final Node<E> prev = x.prev;
  132.  
  133. if (prev == null) {
  134. first = next;
  135. } else {
  136. prev.next = next;
  137. x.prev = null;
  138. }
  139.  
  140. if (next == null) {
  141. last = prev;
  142. } else {
  143. next.prev = prev;
  144. x.next = null;
  145. }
  146.  
  147. x.item = null;
  148. size--;
  149. modCount++;
  150. return element;
  151. }
  152.  
  153. /**
  154. * Returns the first element in this list.
  155. *
  156. * @return the first element in this list
  157. * @throws NoSuchElementException if this list is empty
  158. */
  159. public E getFirst() {
  160. final Node<E> f = first;
  161. if (f == null)
  162. throw new NoSuchElementException();
  163. return f.item;
  164. }
  165.  
  166. /**
  167. * Returns the last element in this list.
  168. *
  169. * @return the last element in this list
  170. * @throws NoSuchElementException if this list is empty
  171. */
  172. public E getLast() {
  173. final Node<E> l = last;
  174. if (l == null)
  175. throw new NoSuchElementException();
  176. return l.item;
  177. }
  178.  
  179. /**
  180. * Removes and returns the first element from this list.
  181. *
  182. * @return the first element from this list
  183. * @throws NoSuchElementException if this list is empty
  184. */
  185. public E removeFirst() {
  186. final Node<E> f = first;
  187. if (f == null)
  188. throw new NoSuchElementException();
  189. return unlinkFirst(f);
  190. }
  191.  
  192. /**
  193. * Removes and returns the last element from this list.
  194. *
  195. * @return the last element from this list
  196. * @throws NoSuchElementException if this list is empty
  197. */
  198. public E removeLast() {
  199. final Node<E> l = last;
  200. if (l == null)
  201. throw new NoSuchElementException();
  202. return unlinkLast(l);
  203. }
  204.  
  205. /**
  206. * Inserts the specified element at the beginning of this list.
  207. *
  208. * @param e the element to add
  209. */
  210. public void addFirst(E e) {
  211. linkFirst(e);
  212. }
  213.  
  214. /**
  215. * Appends the specified element to the end of this list.
  216. *
  217. * <p>This method is equivalent to {@link #add}.
  218. *
  219. * @param e the element to add
  220. */
  221. public void addLast(E e) {
  222. linkLast(e);
  223. }
  224.  
  225. /**
  226. * Returns {@code true} if this list contains the specified element.
  227. * More formally, returns {@code true} if and only if this list contains
  228. * at least one element {@code e} such that
  229. * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
  230. *
  231. * @param o element whose presence in this list is to be tested
  232. * @return {@code true} if this list contains the specified element
  233. */
  234. public boolean contains(Object o) {
  235. return indexOf(o) != -1;
  236. }
  237.  
  238. /**
  239. * Returns the number of elements in this list.
  240. *
  241. * @return the number of elements in this list
  242. */
  243. public int size() {
  244. return size;
  245. }
  246.  
  247. /**
  248. * Appends the specified element to the end of this list.
  249. *
  250. * <p>This method is equivalent to {@link #addLast}.
  251. *
  252. * @param e element to be appended to this list
  253. * @return {@code true} (as specified by {@link Collection#add})
  254. */
  255. public boolean add(E e) {
  256. linkLast(e);
  257. return true;
  258. }
  259.  
  260. /**
  261. * Removes the first occurrence of the specified element from this list,
  262. * if it is present. If this list does not contain the element, it is
  263. * unchanged. More formally, removes the element with the lowest index
  264. * {@code i} such that
  265. * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
  266. * (if such an element exists). Returns {@code true} if this list
  267. * contained the specified element (or equivalently, if this list
  268. * changed as a result of the call).
  269. *
  270. * @param o element to be removed from this list, if present
  271. * @return {@code true} if this list contained the specified element
  272. */
  273. public boolean remove(Object o) {
  274. if (o == null) {
  275. for (Node<E> x = first; x != null; x = x.next) {
  276. if (x.item == null) {
  277. unlink(x);
  278. return true;
  279. }
  280. }
  281. } else {
  282. for (Node<E> x = first; x != null; x = x.next) {
  283. if (o.equals(x.item)) {
  284. unlink(x);
  285. return true;
  286. }
  287. }
  288. }
  289. return false;
  290. }
  291.  
  292. /**
  293. * Appends all of the elements in the specified collection to the end of
  294. * this list, in the order that they are returned by the specified
  295. * collection's iterator. The behavior of this operation is undefined if
  296. * the specified collection is modified while the operation is in
  297. * progress. (Note that this will occur if the specified collection is
  298. * this list, and it's nonempty.)
  299. *
  300. * @param c collection containing elements to be added to this list
  301. * @return {@code true} if this list changed as a result of the call
  302. * @throws NullPointerException if the specified collection is null
  303. */
  304. public boolean addAll(Collection<? extends E> c) {
  305. return addAll(size, c);
  306. }
  307.  
  308. /**
  309. * Inserts all of the elements in the specified collection into this
  310. * list, starting at the specified position. Shifts the element
  311. * currently at that position (if any) and any subsequent elements to
  312. * the right (increases their indices). The new elements will appear
  313. * in the list in the order that they are returned by the
  314. * specified collection's iterator.
  315. *
  316. * @param index index at which to insert the first element
  317. * from the specified collection
  318. * @param c collection containing elements to be added to this list
  319. * @return {@code true} if this list changed as a result of the call
  320. * @throws IndexOutOfBoundsException {@inheritDoc}
  321. * @throws NullPointerException if the specified collection is null
  322. */
  323. public boolean addAll(int index, Collection<? extends E> c) {
  324. checkPositionIndex(index);
  325.  
  326. Object[] a = c.toArray();
  327. int numNew = a.length;
  328. if (numNew == 0)
  329. return false;
  330.  
  331. Node<E> pred, succ;
  332. if (index == size) {
  333. succ = null;
  334. pred = last;
  335. } else {
  336. succ = node(index);
  337. pred = succ.prev;
  338. }
  339.  
  340. for (Object o : a) {
  341. @SuppressWarnings("unchecked") E e = (E) o;
  342. Node<E> newNode = new Node<>(pred, e, null);
  343. if (pred == null)
  344. first = newNode;
  345. else
  346. pred.next = newNode;
  347. pred = newNode;
  348. }
  349.  
  350. if (succ == null) {
  351. last = pred;
  352. } else {
  353. pred.next = succ;
  354. succ.prev = pred;
  355. }
  356.  
  357. size += numNew;
  358. modCount++;
  359. return true;
  360. }
  361.  
  362. /**
  363. * Removes all of the elements from this list.
  364. * The list will be empty after this call returns.
  365. */
  366. public void clear() {
  367. // Clearing all of the links between nodes is "unnecessary", but:
  368. // - helps a generational GC if the discarded nodes inhabit
  369. // more than one generation
  370. // - is sure to free memory even if there is a reachable Iterator
  371. for (Node<E> x = first; x != null; ) {
  372. Node<E> next = x.next;
  373. x.item = null;
  374. x.next = null;
  375. x.prev = null;
  376. x = next;
  377. }
  378. first = last = null;
  379. size = 0;
  380. modCount++;
  381. }
  382.  
  383. // Positional Access Operations
  384.  
  385. /**
  386. * Returns the element at the specified position in this list.
  387. *
  388. * @param index index of the element to return
  389. * @return the element at the specified position in this list
  390. * @throws IndexOutOfBoundsException {@inheritDoc}
  391. */
  392. public E get(int index) {
  393. checkElementIndex(index);
  394. return node(index).item;
  395. }
  396.  
  397. /**
  398. * Replaces the element at the specified position in this list with the
  399. * specified element.
  400. *
  401. * @param index index of the element to replace
  402. * @param element element to be stored at the specified position
  403. * @return the element previously at the specified position
  404. * @throws IndexOutOfBoundsException {@inheritDoc}
  405. */
  406. public E set(int index, E element) {
  407. checkElementIndex(index);
  408. Node<E> x = node(index);
  409. E oldVal = x.item;
  410. x.item = element;
  411. return oldVal;
  412. }
  413.  
  414. /**
  415. * Inserts the specified element at the specified position in this list.
  416. * Shifts the element currently at that position (if any) and any
  417. * subsequent elements to the right (adds one to their indices).
  418. *
  419. * @param index index at which the specified element is to be inserted
  420. * @param element element to be inserted
  421. * @throws IndexOutOfBoundsException {@inheritDoc}
  422. */
  423. public void add(int index, E element) {
  424. checkPositionIndex(index);
  425.  
  426. if (index == size)
  427. linkLast(element);
  428. else
  429. linkBefore(element, node(index));
  430. }
  431.  
  432. /**
  433. * Removes the element at the specified position in this list. Shifts any
  434. * subsequent elements to the left (subtracts one from their indices).
  435. * Returns the element that was removed from the list.
  436. *
  437. * @param index the index of the element to be removed
  438. * @return the element previously at the specified position
  439. * @throws IndexOutOfBoundsException {@inheritDoc}
  440. */
  441. public E remove(int index) {
  442. checkElementIndex(index);
  443. return unlink(node(index));
  444. }
  445.  
  446. /**
  447. * Tells if the argument is the index of an existing element.
  448. */
  449. private boolean isElementIndex(int index) {
  450. return index >= 0 && index < size;
  451. }
  452.  
  453. /**
  454. * Tells if the argument is the index of a valid position for an
  455. * iterator or an add operation.
  456. */
  457. private boolean isPositionIndex(int index) {
  458. return index >= 0 && index <= size;
  459. }
  460.  
  461. /**
  462. * Constructs an IndexOutOfBoundsException detail message.
  463. * Of the many possible refactorings of the error handling code,
  464. * this "outlining" performs best with both server and client VMs.
  465. */
  466. private String outOfBoundsMsg(int index) {
  467. return "Index: "+index+", Size: "+size;
  468. }
  469.  
  470. private void checkElementIndex(int index) {
  471. if (!isElementIndex(index))
  472. throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  473. }
  474.  
  475. private void checkPositionIndex(int index) {
  476. if (!isPositionIndex(index))
  477. throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  478. }
  479.  
  480. /**
  481. * Returns the (non-null) Node at the specified element index.
  482. */
  483. Node<E> node(int index) {
  484. // assert isElementIndex(index);
  485.  
  486. if (index < (size >> 1)) {
  487. Node<E> x = first;
  488. for (int i = 0; i < index; i++)
  489. x = x.next;
  490. return x;
  491. } else {
  492. Node<E> x = last;
  493. for (int i = size - 1; i > index; i--)
  494. x = x.prev;
  495. return x;
  496. }
  497. }
  498.  
  499. // Search Operations
  500.  
  501. /**
  502. * Returns the index of the first occurrence of the specified element
  503. * in this list, or -1 if this list does not contain the element.
  504. * More formally, returns the lowest index {@code i} such that
  505. * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
  506. * or -1 if there is no such index.
  507. *
  508. * @param o element to search for
  509. * @return the index of the first occurrence of the specified element in
  510. * this list, or -1 if this list does not contain the element
  511. */
  512. public int indexOf(Object o) {
  513. int index = 0;
  514. if (o == null) {
  515. for (Node<E> x = first; x != null; x = x.next) {
  516. if (x.item == null)
  517. return index;
  518. index++;
  519. }
  520. } else {
  521. for (Node<E> x = first; x != null; x = x.next) {
  522. if (o.equals(x.item))
  523. return index;
  524. index++;
  525. }
  526. }
  527. return -1;
  528. }
  529.  
  530. /**
  531. * Returns the index of the last occurrence of the specified element
  532. * in this list, or -1 if this list does not contain the element.
  533. * More formally, returns the highest index {@code i} such that
  534. * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
  535. * or -1 if there is no such index.
  536. *
  537. * @param o element to search for
  538. * @return the index of the last occurrence of the specified element in
  539. * this list, or -1 if this list does not contain the element
  540. */
  541. public int lastIndexOf(Object o) {
  542. int index = size;
  543. if (o == null) {
  544. for (Node<E> x = last; x != null; x = x.prev) {
  545. index--;
  546. if (x.item == null)
  547. return index;
  548. }
  549. } else {
  550. for (Node<E> x = last; x != null; x = x.prev) {
  551. index--;
  552. if (o.equals(x.item))
  553. return index;
  554. }
  555. }
  556. return -1;
  557. }
  558.  
  559. // Queue operations.
  560.  
  561. /**
  562. * Retrieves, but does not remove, the head (first element) of this list.
  563. *
  564. * @return the head of this list, or {@code null} if this list is empty
  565. * @since 1.5
  566. */
  567. public E peek() {
  568. final Node<E> f = first;
  569. return (f == null) ? null : f.item;
  570. }
  571.  
  572. /**
  573. * Retrieves, but does not remove, the head (first element) of this list.
  574. *
  575. * @return the head of this list
  576. * @throws NoSuchElementException if this list is empty
  577. * @since 1.5
  578. */
  579. public E element() {
  580. return getFirst();
  581. }
  582.  
  583. /**
  584. * Retrieves and removes the head (first element) of this list.
  585. *
  586. * @return the head of this list, or {@code null} if this list is empty
  587. * @since 1.5
  588. */
  589. public E poll() {
  590. final Node<E> f = first;
  591. return (f == null) ? null : unlinkFirst(f);
  592. }
  593.  
  594. /**
  595. * Retrieves and removes the head (first element) of this list.
  596. *
  597. * @return the head of this list
  598. * @throws NoSuchElementException if this list is empty
  599. * @since 1.5
  600. */
  601. public E remove() {
  602. return removeFirst();
  603. }
  604.  
  605. /**
  606. * Adds the specified element as the tail (last element) of this list.
  607. *
  608. * @param e the element to add
  609. * @return {@code true} (as specified by {@link Queue#offer})
  610. * @since 1.5
  611. */
  612. public boolean offer(E e) {
  613. return add(e);
  614. }
  615.  
  616. // Deque operations
  617. /**
  618. * Inserts the specified element at the front of this list.
  619. *
  620. * @param e the element to insert
  621. * @return {@code true} (as specified by {@link Deque#offerFirst})
  622. * @since 1.6
  623. */
  624. public boolean offerFirst(E e) {
  625. addFirst(e);
  626. return true;
  627. }
  628.  
  629. /**
  630. * Inserts the specified element at the end of this list.
  631. *
  632. * @param e the element to insert
  633. * @return {@code true} (as specified by {@link Deque#offerLast})
  634. * @since 1.6
  635. */
  636. public boolean offerLast(E e) {
  637. addLast(e);
  638. return true;
  639. }
  640.  
  641. /**
  642. * Retrieves, but does not remove, the first element of this list,
  643. * or returns {@code null} if this list is empty.
  644. *
  645. * @return the first element of this list, or {@code null}
  646. * if this list is empty
  647. * @since 1.6
  648. */
  649. public E peekFirst() {
  650. final Node<E> f = first;
  651. return (f == null) ? null : f.item;
  652. }
  653.  
  654. /**
  655. * Retrieves, but does not remove, the last element of this list,
  656. * or returns {@code null} if this list is empty.
  657. *
  658. * @return the last element of this list, or {@code null}
  659. * if this list is empty
  660. * @since 1.6
  661. */
  662. public E peekLast() {
  663. final Node<E> l = last;
  664. return (l == null) ? null : l.item;
  665. }
  666.  
  667. /**
  668. * Retrieves and removes the first element of this list,
  669. * or returns {@code null} if this list is empty.
  670. *
  671. * @return the first element of this list, or {@code null} if
  672. * this list is empty
  673. * @since 1.6
  674. */
  675. public E pollFirst() {
  676. final Node<E> f = first;
  677. return (f == null) ? null : unlinkFirst(f);
  678. }
  679.  
  680. /**
  681. * Retrieves and removes the last element of this list,
  682. * or returns {@code null} if this list is empty.
  683. *
  684. * @return the last element of this list, or {@code null} if
  685. * this list is empty
  686. * @since 1.6
  687. */
  688. public E pollLast() {
  689. final Node<E> l = last;
  690. return (l == null) ? null : unlinkLast(l);
  691. }
  692.  
  693. /**
  694. * Pushes an element onto the stack represented by this list. In other
  695. * words, inserts the element at the front of this list.
  696. *
  697. * <p>This method is equivalent to {@link #addFirst}.
  698. *
  699. * @param e the element to push
  700. * @since 1.6
  701. */
  702. public void push(E e) {
  703. addFirst(e);
  704. }
  705.  
  706. /**
  707. * Pops an element from the stack represented by this list. In other
  708. * words, removes and returns the first element of this list.
  709. *
  710. * <p>This method is equivalent to {@link #removeFirst()}.
  711. *
  712. * @return the element at the front of this list (which is the top
  713. * of the stack represented by this list)
  714. * @throws NoSuchElementException if this list is empty
  715. * @since 1.6
  716. */
  717. public E pop() {
  718. return removeFirst();
  719. }
  720.  
  721. /**
  722. * Removes the first occurrence of the specified element in this
  723. * list (when traversing the list from head to tail). If the list
  724. * does not contain the element, it is unchanged.
  725. *
  726. * @param o element to be removed from this list, if present
  727. * @return {@code true} if the list contained the specified element
  728. * @since 1.6
  729. */
  730. public boolean removeFirstOccurrence(Object o) {
  731. return remove(o);
  732. }
  733.  
  734. /**
  735. * Removes the last occurrence of the specified element in this
  736. * list (when traversing the list from head to tail). If the list
  737. * does not contain the element, it is unchanged.
  738. *
  739. * @param o element to be removed from this list, if present
  740. * @return {@code true} if the list contained the specified element
  741. * @since 1.6
  742. */
  743. public boolean removeLastOccurrence(Object o) {
  744. if (o == null) {
  745. for (Node<E> x = last; x != null; x = x.prev) {
  746. if (x.item == null) {
  747. unlink(x);
  748. return true;
  749. }
  750. }
  751. } else {
  752. for (Node<E> x = last; x != null; x = x.prev) {
  753. if (o.equals(x.item)) {
  754. unlink(x);
  755. return true;
  756. }
  757. }
  758. }
  759. return false;
  760. }
  761.  
  762. /**
  763. * Returns a list-iterator of the elements in this list (in proper
  764. * sequence), starting at the specified position in the list.
  765. * Obeys the general contract of {@code List.listIterator(int)}.<p>
  766. *
  767. * The list-iterator is <i>fail-fast</i>: if the list is structurally
  768. * modified at any time after the Iterator is created, in any way except
  769. * through the list-iterator's own {@code remove} or {@code add}
  770. * methods, the list-iterator will throw a
  771. * {@code ConcurrentModificationException}. Thus, in the face of
  772. * concurrent modification, the iterator fails quickly and cleanly, rather
  773. * than risking arbitrary, non-deterministic behavior at an undetermined
  774. * time in the future.
  775. *
  776. * @param index index of the first element to be returned from the
  777. * list-iterator (by a call to {@code next})
  778. * @return a ListIterator of the elements in this list (in proper
  779. * sequence), starting at the specified position in the list
  780. * @throws IndexOutOfBoundsException {@inheritDoc}
  781. * @see List#listIterator(int)
  782. */
  783. public ListIterator<E> listIterator(int index) {
  784. checkPositionIndex(index);
  785. return new ListItr(index);
  786. }
  787.  
  788. private class ListItr implements ListIterator<E> {
  789. private Node<E> lastReturned = null;
  790. private Node<E> next;
  791. private int nextIndex;
  792. private int expectedModCount = modCount;
  793.  
  794. ListItr(int index) {
  795. // assert isPositionIndex(index);
  796. next = (index == size) ? null : node(index);
  797. nextIndex = index;
  798. }
  799.  
  800. public boolean hasNext() {
  801. return nextIndex < size;
  802. }
  803.  
  804. public E next() {
  805. checkForComodification();
  806. if (!hasNext())
  807. throw new NoSuchElementException();
  808.  
  809. lastReturned = next;
  810. next = next.next;
  811. nextIndex++;
  812. return lastReturned.item;
  813. }
  814.  
  815. public boolean hasPrevious() {
  816. return nextIndex > 0;
  817. }
  818.  
  819. public E previous() {
  820. checkForComodification();
  821. if (!hasPrevious())
  822. throw new NoSuchElementException();
  823.  
  824. lastReturned = next = (next == null) ? last : next.prev;
  825. nextIndex--;
  826. return lastReturned.item;
  827. }
  828.  
  829. public int nextIndex() {
  830. return nextIndex;
  831. }
  832.  
  833. public int previousIndex() {
  834. return nextIndex - 1;
  835. }
  836.  
  837. public void remove() {
  838. checkForComodification();
  839. if (lastReturned == null)
  840. throw new IllegalStateException();
  841.  
  842. Node<E> lastNext = lastReturned.next;
  843. unlink(lastReturned);
  844. if (next == lastReturned)
  845. next = lastNext;
  846. else
  847. nextIndex--;
  848. lastReturned = null;
  849. expectedModCount++;
  850. }
  851.  
  852. public void set(E e) {
  853. if (lastReturned == null)
  854. throw new IllegalStateException();
  855. checkForComodification();
  856. lastReturned.item = e;
  857. }
  858.  
  859. public void add(E e) {
  860. checkForComodification();
  861. lastReturned = null;
  862. if (next == null)
  863. linkLast(e);
  864. else
  865. linkBefore(e, next);
  866. nextIndex++;
  867. expectedModCount++;
  868. }
  869.  
  870. final void checkForComodification() {
  871. if (modCount != expectedModCount)
  872. throw new ConcurrentModificationException();
  873. }
  874. }
  875.  
  876. private static class Node<E> {
  877. E item;
  878. Node<E> next;
  879. Node<E> prev;
  880.  
  881. Node(Node<E> prev, E element, Node<E> next) {
  882. this.item = element;
  883. this.next = next;
  884. this.prev = prev;
  885. }
  886. }
  887.  
  888. /**
  889. * @since 1.6
  890. */
  891. public Iterator<E> descendingIterator() {
  892. return new DescendingIterator();
  893. }
  894.  
  895. /**
  896. * Adapter to provide descending iterators via ListItr.previous
  897. */
  898. private class DescendingIterator implements Iterator<E> {
  899. private final ListItr itr = new ListItr(size());
  900. public boolean hasNext() {
  901. return itr.hasPrevious();
  902. }
  903. public E next() {
  904. return itr.previous();
  905. }
  906. public void remove() {
  907. itr.remove();
  908. }
  909. }
  910.  
  911. @SuppressWarnings("unchecked")
  912. private LinkedList<E> superClone() {
  913. try {
  914. return (LinkedList<E>) super.clone();
  915. } catch (CloneNotSupportedException e) {
  916. throw new InternalError();
  917. }
  918. }
  919.  
  920. /**
  921. * Returns a shallow copy of this {@code LinkedList}. (The elements
  922. * themselves are not cloned.)
  923. *
  924. * @return a shallow copy of this {@code LinkedList} instance
  925. */
  926. public Object clone() {
  927. LinkedList<E> clone = superClone();
  928.  
  929. // Put clone into "virgin" state
  930. clone.first = clone.last = null;
  931. clone.size = 0;
  932. clone.modCount = 0;
  933.  
  934. // Initialize clone with our elements
  935. for (Node<E> x = first; x != null; x = x.next)
  936. clone.add(x.item);
  937.  
  938. return clone;
  939. }
  940.  
  941. /**
  942. * Returns an array containing all of the elements in this list
  943. * in proper sequence (from first to last element).
  944. *
  945. * <p>The returned array will be "safe" in that no references to it are
  946. * maintained by this list. (In other words, this method must allocate
  947. * a new array). The caller is thus free to modify the returned array.
  948. *
  949. * <p>This method acts as bridge between array-based and collection-based
  950. * APIs.
  951. *
  952. * @return an array containing all of the elements in this list
  953. * in proper sequence
  954. */
  955. public Object[] toArray() {
  956. Object[] result = new Object[size];
  957. int i = 0;
  958. for (Node<E> x = first; x != null; x = x.next)
  959. result[i++] = x.item;
  960. return result;
  961. }
  962.  
  963. /**
  964. * Returns an array containing all of the elements in this list in
  965. * proper sequence (from first to last element); the runtime type of
  966. * the returned array is that of the specified array. If the list fits
  967. * in the specified array, it is returned therein. Otherwise, a new
  968. * array is allocated with the runtime type of the specified array and
  969. * the size of this list.
  970. *
  971. * <p>If the list fits in the specified array with room to spare (i.e.,
  972. * the array has more elements than the list), the element in the array
  973. * immediately following the end of the list is set to {@code null}.
  974. * (This is useful in determining the length of the list <i>only</i> if
  975. * the caller knows that the list does not contain any null elements.)
  976. *
  977. * <p>Like the {@link #toArray()} method, this method acts as bridge between
  978. * array-based and collection-based APIs. Further, this method allows
  979. * precise control over the runtime type of the output array, and may,
  980. * under certain circumstances, be used to save allocation costs.
  981. *
  982. * <p>Suppose {@code x} is a list known to contain only strings.
  983. * The following code can be used to dump the list into a newly
  984. * allocated array of {@code String}:
  985. *
  986. * <pre>
  987. * String[] y = x.toArray(new String[0]);</pre>
  988. *
  989. * Note that {@code toArray(new Object[0])} is identical in function to
  990. * {@code toArray()}.
  991. *
  992. * @param a the array into which the elements of the list are to
  993. * be stored, if it is big enough; otherwise, a new array of the
  994. * same runtime type is allocated for this purpose.
  995. * @return an array containing the elements of the list
  996. * @throws ArrayStoreException if the runtime type of the specified array
  997. * is not a supertype of the runtime type of every element in
  998. * this list
  999. * @throws NullPointerException if the specified array is null
  1000. */
  1001. @SuppressWarnings("unchecked")
  1002. public <T> T[] toArray(T[] a) {
  1003. if (a.length < size)
  1004. a = (T[])java.lang.reflect.Array.newInstance(
  1005. a.getClass().getComponentType(), size);
  1006. int i = 0;
  1007. Object[] result = a;
  1008. for (Node<E> x = first; x != null; x = x.next)
  1009. result[i++] = x.item;
  1010.  
  1011. if (a.length > size)
  1012. a[size] = null;
  1013.  
  1014. return a;
  1015. }
  1016.  
  1017. private static final long serialVersionUID = 876323262645176354L;
  1018.  
  1019. /**
  1020. * Saves the state of this {@code LinkedList} instance to a stream
  1021. * (that is, serializes it).
  1022. *
  1023. * @serialData The size of the list (the number of elements it
  1024. * contains) is emitted (int), followed by all of its
  1025. * elements (each an Object) in the proper order.
  1026. */
  1027. private void writeObject(java.io.ObjectOutputStream s)
  1028. throws java.io.IOException {
  1029. // Write out any hidden serialization magic
  1030. s.defaultWriteObject();
  1031.  
  1032. // Write out size
  1033. s.writeInt(size);
  1034.  
  1035. // Write out all elements in the proper order.
  1036. for (Node<E> x = first; x != null; x = x.next)
  1037. s.writeObject(x.item);
  1038. }
  1039.  
  1040. /**
  1041. * Reconstitutes this {@code LinkedList} instance from a stream
  1042. * (that is, deserializes it).
  1043. */
  1044. @SuppressWarnings("unchecked")
  1045. private void readObject(java.io.ObjectInputStream s)
  1046. throws java.io.IOException, ClassNotFoundException {
  1047. // Read in any hidden serialization magic
  1048. s.defaultReadObject();
  1049.  
  1050. // Read in size
  1051. int size = s.readInt();
  1052.  
  1053. // Read in all elements in the proper order.
  1054. for (int i = 0; i < size; i++)
  1055. linkLast((E)s.readObject());
  1056. }
  1057. }

总结
(01) LinkedList 实际上是通过双向链表去实现的。
        它包含一个非常重要的内部类:Entry。Entry是双向链表节点所对应的数据结构,它包括的属性有:当前节点所包含的值上一个节点下一个节点
(02) 从LinkedList的实现方式中可以发现,它不存在LinkedList容量不足的问题。
(03) LinkedList的克隆函数,即是将全部元素克隆到一个新的LinkedList对象中。
(04) LinkedList实现java.io.Serializable。当写入到输出流时,先写入“容量”,再依次写入“每一个节点保护的值”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。
(05) 由于LinkedList实现了Deque,而Deque接口定义了在双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。每种方法都存在两种形式:一种形式在操作失败时抛出异常,另一种形式返回一个特殊值(null 或 false,具体取决于操作)。

总结起来如下表格:

        第一个元素(头部)                 最后一个元素(尾部)
抛出异常 特殊值 抛出异常 特殊值
插入 addFirst(e) offerFirst(e) addLast(e) offerLast(e)
移除 removeFirst() pollFirst() removeLast() pollLast()
检查 getFirst() peekFirst() getLast() peekLast()

(06) LinkedList可以作为FIFO(先进先出)的队列,作为FIFO的队列时,下表的方法等价:

队列方法       等效方法
add(e) addLast(e)
offer(e) offerLast(e)
remove() removeFirst()
poll() pollFirst()
element() getFirst()
peek() peekFirst()

(07) LinkedList可以作为LIFO(后进先出)的栈,作为LIFO的栈时,下表的方法等价:

栈方法        等效方法
push(e) addFirst(e)
pop() removeFirst()
peek() peekFirst()
  • addFirst(e)和offerFirst(e): 查的, 说addXxx是继承自List的, offerXxx是来自Queue.
  • addLast(e)和offerLast(e)
  • 获取: 获取,但不删除元素。
  • getFirst()和peakFirst(): 如果集合为空, 前者抛异常, 后者获取null. 
  • getLast()和peakLast(): 同上
  • : 获取,且删除元素。
  • removeFirst()和pollFirst(): 如果集合为空, 前者抛异常, 后者获取null. 
  • remove()和poll(): 同上
  • removeLast()和pollLast(): 同上

第4部分 LinkedList遍历方式

LinkedList遍历方式

LinkedList支持多种遍历方式。建议不要采用随机访问的方式去遍历LinkedList,而采用逐个遍历的方式。
(01) 第一种,通过迭代器遍历。即通过Iterator去遍历。

for(Iterator iter = list.iterator(); iter.hasNext();)
iter.next();

(02) 通过快速随机访问遍历LinkedList

int size = list.size();
for (int i=0; i<size; i++) {
list.get(i);
}

(03) 通过另外一种for循环来遍历LinkedList

for (Integer integ:list)
;

(04) 通过pollFirst()来遍历LinkedList

while(list.pollFirst() != null)
;

(05) 通过pollLast()来遍历LinkedList

while(list.pollLast() != null)
;

(06) 通过removeFirst()来遍历LinkedList

try {
while(list.removeFirst() != null)
;
} catch (NoSuchElementException e) {
}

(07) 通过removeLast()来遍历LinkedList

try {
while(list.removeLast() != null)
;
} catch (NoSuchElementException e) {
}

测试这些遍历方式效率的代码如下

 /**
* linkedList
* @ClassName: LinkedList_test_1
* @Description:
* @author Xingle
* @date 2014-5-20 上午9:48:33
*
*/
public class LinkedList_test_1 { public static void main(String[] args) { // 通过Iterator遍历LinkedList
iteratorLinkedListThruIterator((LinkedList<Integer>) getLinkedList());
// 通过快速随机访问遍历LinkedList
iteratorLinkedListThruForeach((LinkedList<Integer>) getLinkedList());
// 通过for循环的变种来访问遍历LinkedList
iteratorThroughFor2((LinkedList<Integer>) getLinkedList());
// 通过PollFirst()遍历LinkedList
iteratorThroughPollFirst((LinkedList<Integer>) getLinkedList());
// 通过PollLast()遍历LinkedList
iteratorThroughPollLast((LinkedList<Integer>) getLinkedList());
// 通过removeFirst()遍历LinkedList
iteratorThroughRemoveFirst((LinkedList<Integer>) getLinkedList());
// 通过removeLast()遍历LinkedList
iteratorThroughRemoveLast((LinkedList<Integer>) getLinkedList());
} /**
* 通过RemoveLast()来遍历LinkedList
* @param
* @return
* @author xingle
* @data 2014-5-22 上午11:59:11
*/
private static void iteratorThroughRemoveLast(LinkedList<Integer> list) {
String name = "iteratorThroughRemoveFirst:";
if (list == null)
return;
long start = getCurrentTime();
try {
while (list.removeLast() != null)
;
} catch (NoSuchElementException e) { }
long end = getCurrentTime();
long interval = end - start;
getPrint(name, interval); } /**
* 通过RemoveFirst()来遍历LinkedList
* @param
* @return
* @author xingle
* @data 2014-5-22 上午11:58:36
*/
private static void iteratorThroughRemoveFirst(LinkedList<Integer> list) {
String name = "iteratorThroughRemoveFirst:";
if (list == null)
return;
long start = getCurrentTime();
try {
while (list.removeFirst() != null)
;
} catch (NoSuchElementException e) {
}
long end = getCurrentTime();
long interval = end - start;
getPrint(name, interval); } /**
* 通过pollLast()来遍历LinkedList
* @param
* @return
* @author xingle
* @data 2014-5-22 上午11:57:37
*/
private static void iteratorThroughPollLast(LinkedList<Integer> list) {
String name = "iteratorThroughPollLast:";
if (list == null)
return;
long start = getCurrentTime();
while (list.pollLast() != null)
;
long end = getCurrentTime();
long interval = end - start;
getPrint(name, interval); } /**
* 通过pollFirst()来遍历LinkedList
* @param
* @return
* @author xingle
* @data 2014-5-22 上午11:48:59
*/
private static void iteratorThroughPollFirst(LinkedList<Integer> list) {
String name = "iteratorThroughPollFirst:";
if (list == null)
return;
long start = getCurrentTime();
while (list.pollFirst() != null)
;
long end = getCurrentTime();
long interval = end - start;
getPrint(name, interval);
} /**
*
* @Description:
* @param
* @return
* @author xingle
* @data 2014-5-22 上午11:54:10
*/
private static void getPrint(String name, long interval) {
System.out.println(name + interval + " ms"); } /**
* 获取当前时间
* @Description:
* @param
* @return
* @author xingle
* @data 2014-5-22 上午11:50:29
*/
private static long getCurrentTime() {
long start = System.currentTimeMillis();
return start;
} /**
* 通过快速随机访问遍历LinkedList
*
* @Description:
* @param
* @return
* @author xingle
* @data 2014-5-22 上午11:32:33
*/
private static void iteratorThroughFor2(LinkedList<Integer> list) {
String name = "iteratorLinkedListByForeachRandomAccess:";
if (list == null)
return;
long start = getCurrentTime();
int size = list.size();
for (int i = 0; i < size; i++) {
list.get(i);
}
long end = getCurrentTime();
long interval = end - start;
getPrint(name, interval);
} /**
* 通过另外一种for循环来遍历LinkedList
*
* @Description:
* @param
* @return
* @author xingle
* @data 2014-5-22 上午11:32:31
*/
private static void iteratorLinkedListThruForeach(LinkedList<Integer> list) {
String name = "iteratorThroughForEach:";
if (list == null)
return;
long start = getCurrentTime();
for (Integer i : list)
;
long end = getCurrentTime();
long interval = end - start;
getPrint(name, interval);
} /**
* 通过快迭代器遍历LinkedList
*
* @Description:
* @param
* @return
* @author xingle
* @data 2014-5-22 上午11:32:23
*/
private static void iteratorLinkedListThruIterator(LinkedList<Integer> list) {
String name = "iteratorLinkedListThruIterator:";
if (list == null)
return;
long start = getCurrentTime(); for (Iterator<Integer> iter = list.iterator(); iter.hasNext();)
iter.next();
long end = getCurrentTime();
long interval = end - start;
getPrint(name, interval);
} /**
*
* @Description:
* @param
* @return
* @author xingle
* @data 2014-5-22 上午11:31:58
*/
private static Object getLinkedList() {
LinkedList<Integer> ls = new LinkedList<>();
for (int i = 0; i < 100000; i++)
ls.addLast(i); return ls;
} }

执行结果:

iteratorLinkedListThruIterator:13 ms
iteratorThroughForEach:9 ms
iteratorLinkedListByForeachRandomAccess:6886 ms
iteratorThroughPollFirst:7 ms
iteratorThroughPollLast:7 ms
iteratorThroughRemoveFirst:5 ms
iteratorThroughRemoveFirst:5 ms

由此可见,遍历LinkedList时,使用removeFist()或removeLast()效率最高。但用它们遍历时,会删除原始数据;若单纯只读取,而不删除,应该使用第3种遍历方式。
无论如何,千万不要通过随机访问去遍历LinkedList!


转载:http://www.cnblogs.com/skywang12345/p/3308807.html

Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例的更多相关文章

  1. Java 集合系列 09 HashMap详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  2. Java 集合系列 10 Hashtable详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  3. Java 集合系列 06 Stack详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  4. Java 集合系列 05 Vector详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  5. Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  6. Java 集合系列之 Vector详细介绍(源码解析)和使用示例

    Vector简介 Vector 是矢量队列,它是JDK1.0版本添加的类.继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口. Vector 继承 ...

  7. Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例

    概要  前面,我们已经学习了ArrayList,并了解了fail-fast机制.这一章我们接着学习List的实现类——LinkedList.和学习ArrayList一样,接下来呢,我们先对Linked ...

  8. 【转】Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例

    概要  前面,我们已经学习了ArrayList,并了解了fail-fast机制.这一章我们接着学习List的实现类——LinkedList.和学习ArrayList一样,接下来呢,我们先对Linked ...

  9. Java 集合系列07之 Stack详细介绍(源码解析)和使用示例

    概要 学完Vector了之后,接下来我们开始学习Stack.Stack很简单,它继承于Vector.学习方式还是和之前一样,先对Stack有个整体认识,然后再学习它的源码:最后再通过实例来学会使用它. ...

随机推荐

  1. PythonOCC 3D图形库学习—导入STEP模型

    PythonOCC comes with importers/exporters for the most commonly used standard data files format in en ...

  2. [C和指针]第四部分

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  3. poj 1265 Area (Pick定理+求面积)

    链接:http://poj.org/problem?id=1265 Area Time Limit: 1000MS   Memory Limit: 10000K Total Submissions:  ...

  4. hibernate对象关系实现(四)继承实现

    继承实现方式分为三种:subclass; joined-subclass;union-subclass a.类中体现   b.库中体现分为三种: b.1:一种方式:人和学生公用一张表,添加一个辨别字段 ...

  5. [转载] Linux进程关系

    在工作中, 主进程创建了子进程, 而子进程又创建了孙子进程, 然而子进程被莫名其妙的 kill 了, 结果主进程又启动了一个子进程, 子进程又尝试创建孙子进程, 但是这时候就有问题了, 因为孙子进程还 ...

  6. poj2354Titanic(两点的球面距离)

    链接 球面距离计算公式:d(x1,y1,x2,y2)=r*arccos(sin(x1)*sin(x2)+cos(x1)*cos(x2)*cos(y1-y2)) x1,y1是纬度\经度的弧度单位,r为地 ...

  7. epoll中et+多线程模式中很重要的EPOLL_ONESHOT实验

    因为et模式需要循环读取,但是在读取过程中,如果有新的事件到达,很可能触发了其他线程来处理这个socket,那就乱了. EPOLL_ONESHOT就是用来避免这种情况.注意在一个线程处理完一个sock ...

  8. Android手机分辨率基础知识(DPI,DIP计算)

    1.术语和概念 概念解释 名词 解释 Px (Pixel像素) 不同设备显示效果相同.这里的“相同”是指像素数不会变,比如指定UI长度是100px,那不管分辨率是多少UI长度都是100px.也正是因为 ...

  9. ajax上传文件,并检查文件类型、检查文件大小

    1.使用ajaxfileupload.js的插件,但是对插件做了一处修改,才能够正常使用 修改的部分如下: uploadHttpData: function (r, type) { var data ...

  10. shell脚本中获取本机ip地址的方法

    ipaddr='172.0.0.1' ipaddr=$(ip addr | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/ ...