- 浏览: 538816 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
GGGGeek:
看完了博主的博文,如果没猜错的话应该是浙大吧?很多优秀的人因为 ...
转《D君的故事》 以时刻警示自己 -
游牧民族:
楼主写的不错,学习了,最近对爬虫比较感兴趣,也写了些爬虫相关的 ...
通用爬虫框架及heritrix爬虫介绍 -
jimmee:
jerome_s 写道ice 你怎么看? 粗略的看了一下ice ...
MessagePack, Protocol Buffers和Thrift序列化框架原理和比较说明 -
jerome_s:
ice 你怎么看?
MessagePack, Protocol Buffers和Thrift序列化框架原理和比较说明 -
jimmee:
nk_tocean 写道照着做了,但是不行啊,还是乱码.先确认 ...
hive编写udf处理非utf-8数据
LinkedList的实现其实是一个带哑头节点的双向循环链表。
1.LinkedList的字段
private transient Entry<E> header = new Entry<E>(null, null, null);
//Entry是一个LinkedList的内部类,其实就是链表上的节点,包含两个指针,一个指向
//前面节点,一个指向后面节点
private static class Entry<E> {
E element;
Entry<E> next;
Entry<E> previous;
Entry(E element, Entry<E> next, Entry<E> previous) {
this.element = element;
this.next = next;
this.previous = previous;
}
}
//LinkedList中元素的数量
private transient int size = 0;
最后还有一个继承来的modCount字段。
2.构造方法
/**
* 默认设置哑头节点,其next和previous引用都指向它自己。形成了循环链表
*/
public LinkedList() {
header.next = header.previous = header;
}
3.核心方法:
(1) addBefore方法
//在指定节点前面增加一个节点
private Entry<E> addBefore(E e, Entry<E> entry) {
//首先构建一个新的Entry节点,其next引用指向指定的节点entry,其
//previous引用指定节点原来的前面的节点
Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
//调整newEntry的前面节点的next引用指向newEntry
newEntry.previous.next = newEntry;
//调整newEntry的后面节点的previous引用指向newEntry
newEntry.next.previous = newEntry;
size++;
modCount++;
return newEntry;
}
(2)entry方法
/**
* 得到执行索引位置的节点,如果索引位置在前一半,则从前面开始查找,
若索引位置在后一半,则从后面位置开始查找。
*/
private Entry<E> entry(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+size);
Entry<E> e = header;
if (index < (size >> 1)) { //size>>1等效于size/2,但是移位运算
//效率更高
for (int i = 0; i <= index; i++)
e = e.next;
} else {
for (int i = size; i > index; i--)
e = e.previous;
}
return e;
}
4.有了上面的两个核心方法,增加和删除的方法主要以这两个方法为基础的。
例如,
(1)
public void add(int index, E element) {
//如果在最后增加一个元素,就指定的节点就是哑头节点,由于是循环链表,
//在最后增加一个元素,它的后面的元素当然是头节点了。如果索引位置不是
//在最后,则先用entry方法得到指定索引位置的元素。之后再调用addBefore
//方法。
addBefore(element, (index==size ? header : entry(index)));
}
(2)
//删除指定索引位置的元素,也是先调用entry方法得到相应的元素,再进行删除操作。
public E remove(int index) {
return remove(entry(index));
}
private E remove(Entry<E> e) {
if (e == header)
throw new NoSuchElementException();
E result = e.element;
e.previous.next = e.next;
e.next.previous = e.previous;
e.next = e.previous = null;
e.element = null;
size--;
modCount++;
return result;
}
5.其他方法
(1)
//删除一个对象,分对应的引用o是null还是非null两种情况。
public boolean remove(Object o) {
if (o==null) {
for (Entry<E> e = header.next; e != header; e = e.next) {
if (e.element==null) {
remove(e);
return true;
}
}
} else {
for (Entry<E> e = header.next; e != header; e = e.next) {
if (o.equals(e.element)) {
remove(e);
return true;
}
}
}
return false;
}
(2)
//查找元素o,也是分o为null和非null两种情况,但是不管是哪一种情况,都是顺序查找
public int indexOf(Object o) {
int index = 0;
if (o==null) {
for (Entry e = header.next; e != header; e = e.next) {
if (e.element==null)
return index;
index++;
}
} else {
for (Entry e = header.next; e != header; e = e.next) {
if (o.equals(e.element))
return index;
index++;
}
}
return -1;
}
6. 由于LinkedList实现了双端队列Deque这个接口,因此,也具有双端队列操作的相关方法。因此,LinkedList可以当作先进先出的队列使用,也可以当作先进后出的堆栈使用。
7. LinkedList实现了迭代器
但是,这个迭代器的是实现ListIterator接口的,也就是说,可以向前或者向后进行迭代。
1.LinkedList的字段
private transient Entry<E> header = new Entry<E>(null, null, null);
//Entry是一个LinkedList的内部类,其实就是链表上的节点,包含两个指针,一个指向
//前面节点,一个指向后面节点
private static class Entry<E> {
E element;
Entry<E> next;
Entry<E> previous;
Entry(E element, Entry<E> next, Entry<E> previous) {
this.element = element;
this.next = next;
this.previous = previous;
}
}
//LinkedList中元素的数量
private transient int size = 0;
最后还有一个继承来的modCount字段。
2.构造方法
/**
* 默认设置哑头节点,其next和previous引用都指向它自己。形成了循环链表
*/
public LinkedList() {
header.next = header.previous = header;
}
3.核心方法:
(1) addBefore方法
//在指定节点前面增加一个节点
private Entry<E> addBefore(E e, Entry<E> entry) {
//首先构建一个新的Entry节点,其next引用指向指定的节点entry,其
//previous引用指定节点原来的前面的节点
Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
//调整newEntry的前面节点的next引用指向newEntry
newEntry.previous.next = newEntry;
//调整newEntry的后面节点的previous引用指向newEntry
newEntry.next.previous = newEntry;
size++;
modCount++;
return newEntry;
}
(2)entry方法
/**
* 得到执行索引位置的节点,如果索引位置在前一半,则从前面开始查找,
若索引位置在后一半,则从后面位置开始查找。
*/
private Entry<E> entry(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+size);
Entry<E> e = header;
if (index < (size >> 1)) { //size>>1等效于size/2,但是移位运算
//效率更高
for (int i = 0; i <= index; i++)
e = e.next;
} else {
for (int i = size; i > index; i--)
e = e.previous;
}
return e;
}
4.有了上面的两个核心方法,增加和删除的方法主要以这两个方法为基础的。
例如,
(1)
public void add(int index, E element) {
//如果在最后增加一个元素,就指定的节点就是哑头节点,由于是循环链表,
//在最后增加一个元素,它的后面的元素当然是头节点了。如果索引位置不是
//在最后,则先用entry方法得到指定索引位置的元素。之后再调用addBefore
//方法。
addBefore(element, (index==size ? header : entry(index)));
}
(2)
//删除指定索引位置的元素,也是先调用entry方法得到相应的元素,再进行删除操作。
public E remove(int index) {
return remove(entry(index));
}
private E remove(Entry<E> e) {
if (e == header)
throw new NoSuchElementException();
E result = e.element;
e.previous.next = e.next;
e.next.previous = e.previous;
e.next = e.previous = null;
e.element = null;
size--;
modCount++;
return result;
}
5.其他方法
(1)
//删除一个对象,分对应的引用o是null还是非null两种情况。
public boolean remove(Object o) {
if (o==null) {
for (Entry<E> e = header.next; e != header; e = e.next) {
if (e.element==null) {
remove(e);
return true;
}
}
} else {
for (Entry<E> e = header.next; e != header; e = e.next) {
if (o.equals(e.element)) {
remove(e);
return true;
}
}
}
return false;
}
(2)
//查找元素o,也是分o为null和非null两种情况,但是不管是哪一种情况,都是顺序查找
public int indexOf(Object o) {
int index = 0;
if (o==null) {
for (Entry e = header.next; e != header; e = e.next) {
if (e.element==null)
return index;
index++;
}
} else {
for (Entry e = header.next; e != header; e = e.next) {
if (o.equals(e.element))
return index;
index++;
}
}
return -1;
}
6. 由于LinkedList实现了双端队列Deque这个接口,因此,也具有双端队列操作的相关方法。因此,LinkedList可以当作先进先出的队列使用,也可以当作先进后出的堆栈使用。
7. LinkedList实现了迭代器
但是,这个迭代器的是实现ListIterator接口的,也就是说,可以向前或者向后进行迭代。
发表评论
-
[转载]并发之痛 Thread,Goroutine,Actor
2017-04-06 19:21 590转自 http://jolestar.com/pa ... -
JVM动态调整字节码
2016-04-14 19:27 1226粗略的点开btrace的源码看了一下,实际上他只是封装了JD ... -
java字节码常量池处理说明
2016-04-13 23:23 11101. 根据java的字节码格式说明,常量池中每一项的大小不一 ... -
Mac OSX 10.10 Yosemite编译OpenJDK 8
2016-04-03 18:14 3500编译时间:2016-04-03 系统版本:Mac OS ... -
Java 并发之 ConcurrentSkipListMap 简述
2015-09-20 20:24 1123JCIP 提到了在 Java 6 中引入了两个新的并发集合类 ... -
hbase等源码导入eclipse流程
2015-09-20 19:00 1715hbase: 1. 下载源码 svn co ht ... -
最简单的平衡树(红-黑树)的实现
2015-09-04 08:04 1186在二叉搜索树(BST)的基础上,要实现一颗平衡树,可以使用 ... -
多线程程序中操作的原子性[转载]
2014-12-06 10:49 11630. 背景 原子操作就是不可再分的操作。在多线程程序中原子 ... -
6. 内存屏障[转载]
2014-11-26 00:07 713原文地址 作者:Martin Thompson 译者: ... -
5.合并写(write combining)[转载]
2014-11-25 21:54 733原文地址 译者:无叶 ... -
4. 内存访问模型的重要性[转载]
2014-11-25 21:53 1065在高性能的计算中,我 ... -
3. Java 7与伪共享的新仇旧恨[转载]
2014-11-25 21:45 875原文:False Shareing && J ... -
2. 伪共享(False Sharing)[转载]
2014-11-25 21:40 855作者:Martin Thompson 译者:丁一 缓存 ... -
lucene索引创建的理解思路
2014-06-29 23:12 1481虽然lucene4很早就出来,但是这里仍然以lucene3. ... -
lucene的拼写检查的实现原理
2014-06-08 18:19 13101. 建索引时, 使用ngram的方式创建索引 Sp ... -
字符串相似算法-(3) NGram Distance
2014-06-08 17:54 4893就是N-Gram version of edit dista ... -
字符串相似算法-(2) Levenshtein distance
2014-06-08 16:32 2219编辑距离概念描述: ... -
字符串相似算法-(1) Jaro-Winkler Distance
2014-06-08 12:05 6751Jaro-Winkler Distance 算法 ... -
tomcat参数编码处理过程
2014-06-07 09:49 18371. org.apache.coyote.http11 ... -
SSLEngine的示例
2014-05-26 19:44 7819为什么要使用SSLEngine, 参考javadoc的说明 ...
相关推荐
Java集合框架是面试常考内容,包括List、Set、Map接口以及其实现类。如ArrayList、LinkedList、HashMap、HashSet等的内部实现原理,比如它们的扩容策略、线程安全问题以及各种操作的时间复杂度分析,这些都是源码...
3. 集合框架:ArrayList、LinkedList、HashMap等数据结构的实现,以及它们在不同场景下的性能差异。 4. 多线程:Java并发库的使用,如synchronized、volatile、ThreadLocal等关键字,以及ExecutorService和Future...
在Java面试中,源码解读是一项重要的能力,它考察了开发者对Java语言底层实现的理解以及问题解决的能力。这里我们将深入探讨三道常见的Java面试题,它们涵盖了基础、并发和集合框架等方面,帮助你提升对Java源码的...
本篇文章将对Java API的部分关键组件进行源码解读,帮助读者深入理解其工作原理。 1. **对象创建与内存管理**: - `Object`类:所有Java类的基类,包含了如`clone()`, `equals()`, `hashCode()`等方法。理解`...
在"java集合源码-analysis:java集合源码解析"这个项目中,我们主要探讨的是对Java集合框架的源码进行深入理解。下面将详细阐述Java集合框架的基本概念、重要类和接口,以及其源码分析的重要性。 Java集合框架主要...
Java集合框架源码解读(1)——ArrayList、LinkedList和Vector Java集合框架源码解读(2)——HashMap Java集合框架源码解读(3)——LinkedHashMap Java集合框架源码解读(4)——WeakHashMap Java集合框架源码解读
java forkjoin 源码 -- -- geomesa -- spring -- 算法 -- hbase -- 数据库 -- 高并发 [Java Memory Modle内存模型] [指令重排,可见性,原子性,顺序一致性] 并发同步处理 [乐观锁&悲观锁,重入锁&非重入锁,公平锁&...
《Java源码解读——深入理解JDK》 Java作为一门广泛应用的编程语言,其源码是许多开发者探索技术原理、提升编程技能的重要资源。"java源码解读-jdk_reading:java源码日常阅读与注解"项目,旨在帮助开发者深入理解...
java所有集合类底层源码解析汇总,包括ArrayList、HashMap、HashSet、LinkedList、TreeMap、HashSet、ConcurrentHashMap等集合框架的底层实现源码大白话解读。
《核心Java视频源码》是一套专注于讲解Java编程基础与进阶内容的教育资源。通过分析提供的压缩包文件名称,我们可以推断出这可能是一个按章节组织的教程,涵盖了从基础到高级的不同主题。以下是根据章节名称对每个...
总之,"Java8-basic-source-code-interpretation"项目旨在通过源码解读,帮助开发者深入理解`int`在Java 8中的各种使用场景、操作方式以及相关的新特性。通过对这个项目的探索,开发者可以提升自己在Java编程中的...
3. **集合框架**:在订单处理系统中,可能会用到ArrayList、LinkedList、HashMap等集合类来存储和管理订单数据。理解如何操作这些集合,以及它们各自的性能特点,对分析源码很有帮助。 4. **多线程**:Java提供了...
4. **集合框架**:Java集合框架是存储和操作对象的重要工具,包括ArrayList、LinkedList、HashSet、HashMap等。学习笔记会详细解析各种集合类的特性和使用场景。 5. **输入/输出(I/O)**:Java I/O流用于读写文件、...
本文将围绕达内的Core Java培训源码,对其中的关键知识点进行详细解读。 一、Java基础 1. 类与对象:Java是一种面向对象的语言,类是对象的模板,对象则是类的实例。理解类的定义、对象的创建及成员变量和方法的...
源码解读是提升技术水平的重要途径。例如,深入理解HashMap和ConcurrentHashMap的实现,可以让我们更好地利用这些数据结构,避免性能瓶颈;阅读ArrayList和LinkedList的源码,有助于我们选择合适的数据结构以优化...
Java中的LinkedList是一个实现了List接口的双向链表数据结构。它提供了高效的插入和删除操作,但随机访问性能相对较差。LinkedList的实现方式使得它在需要频繁进行添加、删除操作且顺序访问较多的场景下表现优越。 ...
Java作为一门广泛使用的编程语言,其底层知识点和源码解读对于深入理解并优化代码性能至关重要。本主题将探讨以下几个方面: 1. **Java虚拟机(JVM)**: JVM是Java程序运行的基础,它负责字节码的解释执行,内存...
3. **集合框架**:`java.util`包下的集合类,如`ArrayList`、`HashMap`和`LinkedList`的源码揭示了数据结构和算法的应用。例如,`HashMap`是如何实现高效的查找和插入,`ArrayList`的动态扩容策略。 4. **并发编程*...
- `ArrayList`, `LinkedList`, `HashSet`, `HashMap`等集合类的使用,展示了Java集合框架的强大功能,包括动态扩容、迭代器、泛型等。 7. **多线程**: - `Thread`类的子类化,`Runnable`接口的实现,线程同步...
这份"Java基础面试题源码资料.zip"包含了丰富的面试题目和源代码,旨在帮助求职者或开发者提升Java技术水平,更好地应对面试挑战。以下将对Java基础面试题中的核心知识点进行详细解读。 1. **Java语法基础** - **...